From 7d49cc66361ab5e3818ba77e03b69406d85616e0 Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Fri, 24 May 2024 21:47:38 +0100
Subject: [PATCH 1/6] Have freecam on death and also allow for first person
following of pmcs
---
Source/Configuration/PluginConfigSettings.cs | 4 +-
Source/Coop/FreeCamera/FreeCamera.cs | 189 ++++++++++++++----
.../Coop/FreeCamera/FreeCameraController.cs | 180 ++++++++---------
3 files changed, 238 insertions(+), 135 deletions(-)
diff --git a/Source/Configuration/PluginConfigSettings.cs b/Source/Configuration/PluginConfigSettings.cs
index c92b2ecbd..3cc4c2c1e 100644
--- a/Source/Configuration/PluginConfigSettings.cs
+++ b/Source/Configuration/PluginConfigSettings.cs
@@ -121,12 +121,12 @@ public bool SETTING_DEBUGShowPlayerList
public int WaitingTimeBeforeStart { get; private set; }
- public int BlackScreenOnDeathTime
+ public float BlackScreenOnDeathTime
{
get
{
return StayInTarkovPlugin.Instance.Config.Bind
- ("Coop", "BlackScreenOnDeathTime", 500, new ConfigDescription("How long to wait until your death waits to become a Free Camera")).Value;
+ ("Coop", "BlackScreenOnDeathTime", 5F, new ConfigDescription("How long to wait after death until you become a Free Camera")).Value;
}
}
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index f516ec0ea..885ec6ffc 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -1,4 +1,9 @@
-using JetBrains.Annotations;
+#nullable enable
+
+using StayInTarkov.Coop.Components.CoopGameComponents;
+using StayInTarkov.Coop.Players;
+using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
namespace StayInTarkov.Coop.FreeCamera
@@ -10,85 +15,195 @@ namespace StayInTarkov.Coop.FreeCamera
/// https://gist.github.com/ashleydavis/f025c03a9221bc840a2b
///
/// This is HEAVILY based on Terkoiz's work found here. Thanks for your work Terkoiz!
- /// https://dev.sp-tarkov.com/Terkoiz/Freecam/raw/branch/master/project/Terkoiz.Freecam/FreecamController.cs
+ /// https://dev.sp-tarkov.com/Terkoiz/Freecam/raw/branch/master/project/Terkoiz.Freecam/Freecam.cs
///
public class FreeCamera : MonoBehaviour
{
+ private CoopPlayer? _playerSpectating;
+ private bool _isSpectatingPlayer = false;
+
public bool IsActive = false;
- [UsedImplicitly]
- public void Update()
+ private void StopSpectatingPlayer()
{
- if (!IsActive)
+ if (_playerSpectating != null)
{
- return;
+ _playerSpectating = null;
}
+ if (_isSpectatingPlayer)
+ {
+ _isSpectatingPlayer = false;
+ transform.parent = null;
+ }
+ }
+
+ private void SpectateNextPlayer()
+ {
+ UpdatePlayerSpectator(true);
+ }
- var fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
- var movementSpeed = fastMode ? 20f : 3f;
+ private void SpectatePreviousPlayer()
+ {
+ UpdatePlayerSpectator(false);
+ }
+ ///
+ /// Updates the player beign followed by the camera
+ ///
+ /// True for the next player and false for the previous player
+ private void UpdatePlayerSpectator(bool nextPlayer)
+ {
+ List players = [.. SITGameComponent.GetCoopGameComponent()
+ .Players
+ .Values
+ .Where(x => !x.IsYourPlayer && !x.IsAI && x.HealthController.IsAlive)
+ ];
+ if (players.Count > 0)
+ {
+ if (_playerSpectating == null)
+ {
+ if (players[0] != null)
+ {
+ _playerSpectating = players[0];
+ }
+ }
+ else
+ {
+ // We want to look for the next player
+ if (nextPlayer)
+ {
+ int playerIndex = players.IndexOf(_playerSpectating) + 1;
+ if (players.Count - 1 >= playerIndex)
+ {
+ _playerSpectating = players[playerIndex];
+ }
+ else
+ {
+ _playerSpectating = players[0];
+ }
+ }
+ // We are going backwards looking for the previous player
+ else
+ {
+ int playerIndex = players.IndexOf(_playerSpectating) - 1;
+ if (playerIndex >= 0)
+ {
+ _playerSpectating = players[playerIndex];
+ }
+ else
+ {
+ _playerSpectating = players[players.Count - 1];
+ }
+ }
+
+ }
+
+ if (_playerSpectating != null)
+ {
+ // Attach the camera to the player we are spectating;
+ transform.parent = _playerSpectating?.PlayerBones.Head.Original;
+ transform.localPosition = new Vector3(-0.05f, 0.17f, 0f);
+ transform.localEulerAngles = new Vector3(260, 80, 0);
+ _isSpectatingPlayer = true;
+ }
+ }
+ else
+ {
+ StopSpectatingPlayer();
+ }
+ }
+
+ private void MoveAndRotateCamera()
+ {
+ bool fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
+ float movementSpeed = fastMode ? 20f : 3f;
+
+ // Strafe Right
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
transform.position += (-transform.right * (movementSpeed * Time.deltaTime));
}
+ // Strafe Left
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.position += (transform.right * (movementSpeed * Time.deltaTime));
}
+ // Forwards
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.position += (transform.forward * (movementSpeed * Time.deltaTime));
}
+ // Backwards
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.position += (-transform.forward * (movementSpeed * Time.deltaTime));
}
- if (true)
+ // Up
+ if (Input.GetKey(KeyCode.Q))
{
- if (Input.GetKey(KeyCode.Q))
- {
- transform.position += (transform.up * (movementSpeed * Time.deltaTime));
- }
+ transform.position += (transform.up * (movementSpeed * Time.deltaTime));
+ }
- if (Input.GetKey(KeyCode.E))
- {
- transform.position += (-transform.up * (movementSpeed * Time.deltaTime));
- }
+ // Down
+ if (Input.GetKey(KeyCode.E))
+ {
+ transform.position += (-transform.up * (movementSpeed * Time.deltaTime));
+ }
- if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp))
- {
- transform.position += (Vector3.up * (movementSpeed * Time.deltaTime));
- }
+ // Up
+ if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp))
+ {
+ transform.position += (Vector3.up * (movementSpeed * Time.deltaTime));
+ }
- if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown))
- {
- transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime));
- }
+ // Down
+ if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown))
+ {
+ transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime));
}
float newRotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * 3f;
float newRotationY = transform.localEulerAngles.x - Input.GetAxis("Mouse Y") * 3f;
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
-
- //if (FreecamPlugin.CameraMousewheelZoom.Value)
- //{
- // float axis = Input.GetAxis("Mouse ScrollWheel");
- // if (axis != 0)
- // {
- // var zoomSensitivity = fastMode ? FreecamPlugin.CameraFastZoomSpeed.Value : FreecamPlugin.CameraZoomSpeed.Value;
- // transform.position += transform.forward * (axis * zoomSensitivity);
- // }
- //}
}
- [UsedImplicitly]
- private void OnDestroy()
+ protected void OnDestroy()
{
Destroy(this);
}
+
+ protected void Update()
+ {
+ if (!IsActive)
+ {
+ return;
+ }
+
+ // Spectate the next player
+ if (Input.GetKey(KeyCode.Mouse0))
+ {
+ SpectateNextPlayer();
+ }
+ // Spectate the previous player
+ else if (Input.GetKey(KeyCode.Mouse1))
+ {
+ SpectatePreviousPlayer();
+ }
+ // Stop following the currently selected player
+ else if (Input.GetKey(KeyCode.End))
+ {
+ StopSpectatingPlayer();
+ }
+
+ // If we aren't spectating anyone then just update the camera normally
+ if (!_isSpectatingPlayer)
+ {
+ MoveAndRotateCamera();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Source/Coop/FreeCamera/FreeCameraController.cs b/Source/Coop/FreeCamera/FreeCameraController.cs
index 71676ec26..6cd49a17e 100644
--- a/Source/Coop/FreeCamera/FreeCameraController.cs
+++ b/Source/Coop/FreeCamera/FreeCameraController.cs
@@ -1,13 +1,15 @@
-using BSG.CameraEffects;
+using BepInEx.Logging;
+using BSG.CameraEffects;
using Comfort.Common;
using EFT;
using EFT.CameraControl;
using EFT.UI;
-using HarmonyLib;
using StayInTarkov.Configuration;
using StayInTarkov.Coop.Components.CoopGameComponents;
+using StayInTarkov.Coop.Players;
using StayInTarkov.Coop.SITGameModes;
using System;
+using System.Collections;
using UnityEngine;
using UnityStandardAssets.ImageEffects;
@@ -27,15 +29,19 @@ public class FreeCameraController : MonoBehaviour
private bool _uiHidden;
private GamePlayerOwner _gamePlayerOwner;
+ private DateTime _lastTime = DateTime.MinValue;
+
+ private ManualLogSource Logger { get; } = BepInEx.Logging.Logger.CreateLogSource("FreeCameraController");
+ private CoopPlayer Player => (CoopPlayer) Singleton.Instance.MainPlayer;
public GameObject CameraParent { get; set; }
public Camera CameraFreeCamera { get; private set; }
public Camera CameraMain { get; private set; }
- void Awake()
+ protected void Awake()
{
CameraParent = new GameObject("CameraParent");
- var FCamera = CameraParent.GetOrAddComponent();
+ Camera FCamera = CameraParent.GetOrAddComponent();
FCamera.enabled = false;
}
@@ -61,107 +67,100 @@ public void Start()
{
return;
}
+
+ Player.OnPlayerDead += Player_OnPlayerDead;
}
- private DateTime _lastTime = DateTime.MinValue;
+ private IEnumerator PlayerDeathRoutine()
+ {
+ yield return new WaitForSeconds(PluginConfigSettings.Instance.CoopSettings.BlackScreenOnDeathTime);
+
+ var fpsCamInstance = CameraClass.Instance;
+ if (fpsCamInstance == null)
+ {
+ Logger.LogDebug("fpsCamInstance for camera is null");
+ yield break;
+ }
- int DeadTime = 0;
+ // Reset FOV after died
+ if (fpsCamInstance.Camera != null)
+ fpsCamInstance.Camera.fieldOfView = Singleton.Instance.Game.Settings.FieldOfView;
+
+ EffectsController effectsController = fpsCamInstance.EffectsController;
+ if (effectsController == null)
+ {
+ Logger.LogDebug("effects controller for camera is null");
+ yield break;
+ }
+
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ DisableAndDestroyEffect(effectsController.GetComponent());
+ //DisableAndDestroyEffect(effectsController.GetComponent());
+
+ var ccBlends = fpsCamInstance.EffectsController.GetComponents();
+ if (ccBlends != null)
+ foreach (var ccBlend in ccBlends)
+ DisableAndDestroyEffect(ccBlend);
+
+ DisableAndDestroyEffect(fpsCamInstance.VisorEffect);
+ DisableAndDestroyEffect(fpsCamInstance.NightVision);
+ DisableAndDestroyEffect(fpsCamInstance.ThermalVision);
+
+ // Go to free camera mode
+ ToggleCamera();
+ ToggleUi();
+ }
+
+ private void Player_OnPlayerDead(EFT.Player player, IPlayer lastAggressor, DamageInfo damageInfo, EBodyPart part)
+ {
+ Player.OnPlayerDead -= Player_OnPlayerDead;
+ StartCoroutine(PlayerDeathRoutine());
+ }
public void Update()
{
if (_gamePlayerOwner == null)
return;
- if (_gamePlayerOwner.Player == null)
+ if (Player == null)
return;
- if (_gamePlayerOwner.Player.PlayerHealthController == null)
+ if (Player.PlayerHealthController == null)
return;
- if (!SITGameComponent.TryGetCoopGameComponent(out var coopGC))
+ if (!SITGameComponent.TryGetCoopGameComponent(out SITGameComponent coopGC))
return;
- var coopGame = coopGC.LocalGameInstance as CoopSITGame;
+ CoopSITGame coopGame = coopGC.LocalGameInstance as CoopSITGame;
if (coopGame == null)
return;
var quitState = coopGC.GetQuitState();
-
- if (_gamePlayerOwner.Player.PlayerHealthController.IsAlive
- && (Input.GetKey(KeyCode.F9) || (quitState != SITGameComponent.EQuitState.NONE && !_freeCamScript.IsActive))
- && _lastTime < DateTime.Now.AddSeconds(-3))
+ if (Player.PlayerHealthController.IsAlive &&
+ (Input.GetKey(KeyCode.F9) || (quitState != SITGameComponent.EQuitState.NONE && !_freeCamScript.IsActive)) &&
+ _lastTime < DateTime.Now.AddSeconds(-3))
{
_lastTime = DateTime.Now;
ToggleCamera();
ToggleUi();
- }
-
- if (!_gamePlayerOwner.Player.PlayerHealthController.IsAlive)
- {
- // This is to make sure the screen effect remove code only get executed once, instead of running every frame.
- if (DeadTime == -1)
- return;
-
- if (DeadTime < PluginConfigSettings.Instance.CoopSettings.BlackScreenOnDeathTime)
- {
- DeadTime++;
- }
- else
- {
- DeadTime = -1;
-
- var fpsCamInstance = CameraClass.Instance;
- if (fpsCamInstance == null)
- return;
-
- // Reset FOV after died
- if (fpsCamInstance.Camera != null)
- fpsCamInstance.Camera.fieldOfView = Singleton.Instance.Game.Settings.FieldOfView;
-
- var effectsController = fpsCamInstance.EffectsController;
- if (effectsController == null)
- return;
-
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- DisableAndDestroyEffect(effectsController.GetComponent());
- //DisableAndDestroyEffect(effectsController.GetComponent());
-
- var ccBlends = fpsCamInstance.EffectsController.GetComponents();
- if (ccBlends != null)
- foreach (var ccBlend in ccBlends)
- DisableAndDestroyEffect(ccBlend);
-
- DisableAndDestroyEffect(fpsCamInstance.VisorEffect);
- DisableAndDestroyEffect(fpsCamInstance.NightVision);
- DisableAndDestroyEffect(fpsCamInstance.ThermalVision);
-
- // Go to free camera mode
- ToggleCamera();
- ToggleUi();
- }
- }
+ }
}
- //DateTime? _lastOcclusionCullCheck = null;
- //Vector3? _playerDeathOrExitPosition;
- //bool showAtDeathOrExitPosition;
-
///
/// Toggles the Freecam mode
///
public void ToggleCamera()
{
// Get our own Player instance. Null means we're not in a raid
- var localPlayer = GetLocalPlayerFromWorld();
- if (localPlayer == null)
+ if (Player == null)
return;
if (!_freeCamScript.IsActive)
@@ -169,16 +168,14 @@ public void ToggleCamera()
GameObject[] allGameObject = Resources.FindObjectsOfTypeAll();
foreach (GameObject gobj in allGameObject)
{
- if (gobj.GetComponent() != null)
- {
- gobj.GetComponent().ForceEnable(true);
- }
+ gobj.GetComponent()?.ForceEnable(true);
}
- SetPlayerToFreecamMode(localPlayer);
+ Logger.LogDebug($"Enabled Culling on {allGameObject.Length}.");
+ SetPlayerToFreecamMode(Player);
}
else
{
- SetPlayerToFirstPersonMode(localPlayer);
+ SetPlayerToFirstPersonMode(Player);
}
}
@@ -188,21 +185,20 @@ public void ToggleCamera()
public void ToggleUi()
{
// Check if we're currently in a raid
- if (GetLocalPlayerFromWorld() == null)
+ if (Player == null)
return;
// If we don't have the UI Component cached, go look for it in the scene
if (_playerUi == null)
{
- var gameObject = GameObject.Find("BattleUIScreen");
+ GameObject gameObject = GameObject.Find("BattleUIScreen");
if (gameObject == null)
return;
_playerUi = gameObject.GetComponent();
-
if (_playerUi == null)
{
- //FreecamPlugin.Logger.LogError("Failed to locate player UI");
+ Logger.LogError("Failed to locate player UI");
return;
}
}
@@ -224,11 +220,9 @@ private void SetPlayerToFreecamMode(EFT.Player localPlayer)
// This means our character will be fully visible, while letting the camera move freely
localPlayer.PointOfView = EPointOfView.ThirdPerson;
- // Get the PlayerBody reference. It's a protected field, so we have to use traverse to fetch it
- var playerBody = Traverse.Create(localPlayer).Field("_playerBody").Value;
- if (playerBody != null)
+ if (localPlayer.PlayerBody != null)
{
- playerBody.PointOfView.Value = EPointOfView.FreeCamera;
+ localPlayer.PlayerBody.PointOfView.Value = EPointOfView.FreeCamera;
localPlayer.GetComponent().UpdatePointOfView();
}
@@ -244,12 +238,6 @@ private void SetPlayerToFirstPersonMode(EFT.Player localPlayer)
{
_freeCamScript.IsActive = false;
- //if (FreecamPlugin.CameraRememberLastPosition.Value)
- //{
- // _lastPosition = _mainCamera.transform.position;
- // _lastRotation = _mainCamera.transform.rotation;
- //}
-
// re-enable _gamePlayerOwner
_gamePlayerOwner.enabled = true;
@@ -265,7 +253,7 @@ private void SetPlayerToFirstPersonMode(EFT.Player localPlayer)
private EFT.Player GetLocalPlayerFromWorld()
{
// If the GameWorld instance is null or has no RegisteredPlayers, it most likely means we're not in a raid
- var gameWorld = Singleton.Instance;
+ GameWorld gameWorld = Singleton.Instance;
if (gameWorld == null || gameWorld.MainPlayer == null)
return null;
@@ -284,7 +272,7 @@ public void DisableAndDestroyEffect(MonoBehaviour effect)
public void OnDestroy()
{
- GameObject.Destroy(CameraParent);
+ Destroy(CameraParent);
// Destroy FreeCamScript before FreeCamController if exists
Destroy(_freeCamScript);
From af3ed699dbaef146680b24f5f41efa70d247684c Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Sat, 25 May 2024 20:07:27 +0100
Subject: [PATCH 2/6] filter to only human players
---
Source/Coop/FreeCamera/FreeCamera.cs | 10 ++++++----
Source/Coop/FreeCamera/FreeCameraController.cs | 1 -
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index 885ec6ffc..6edecb15a 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -33,8 +33,8 @@ private void StopSpectatingPlayer()
if (_isSpectatingPlayer)
{
_isSpectatingPlayer = false;
- transform.parent = null;
}
+ transform.parent = null;
}
private void SpectateNextPlayer()
@@ -53,11 +53,13 @@ private void SpectatePreviousPlayer()
/// True for the next player and false for the previous player
private void UpdatePlayerSpectator(bool nextPlayer)
{
- List players = [.. SITGameComponent.GetCoopGameComponent()
+ SITGameComponent coopGameComponent = SITGameComponent.GetCoopGameComponent();
+ List players = [.. coopGameComponent
.Players
.Values
- .Where(x => !x.IsYourPlayer && !x.IsAI && x.HealthController.IsAlive)
+ .Where(x => !x.IsYourPlayer && x.HealthController.IsAlive && x.GroupId?.Contains("SIT") == true)
];
+
if (players.Count > 0)
{
if (_playerSpectating == null)
@@ -102,7 +104,7 @@ private void UpdatePlayerSpectator(bool nextPlayer)
{
// Attach the camera to the player we are spectating;
transform.parent = _playerSpectating?.PlayerBones.Head.Original;
- transform.localPosition = new Vector3(-0.05f, 0.17f, 0f);
+ transform.localPosition = new Vector3(-0.05f, 0.17f, -0.5f);
transform.localEulerAngles = new Vector3(260, 80, 0);
_isSpectatingPlayer = true;
}
diff --git a/Source/Coop/FreeCamera/FreeCameraController.cs b/Source/Coop/FreeCamera/FreeCameraController.cs
index 6cd49a17e..e0f0126c4 100644
--- a/Source/Coop/FreeCamera/FreeCameraController.cs
+++ b/Source/Coop/FreeCamera/FreeCameraController.cs
@@ -170,7 +170,6 @@ public void ToggleCamera()
{
gobj.GetComponent()?.ForceEnable(true);
}
- Logger.LogDebug($"Enabled Culling on {allGameObject.Length}.");
SetPlayerToFreecamMode(Player);
}
else
From e26eb32970bbdeed3ff490149cd93e1a8d61546f Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Sun, 26 May 2024 10:39:05 +0100
Subject: [PATCH 3/6] I went too far with the position
---
Source/Coop/FreeCamera/FreeCamera.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index 6edecb15a..c705e8e14 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -104,7 +104,7 @@ private void UpdatePlayerSpectator(bool nextPlayer)
{
// Attach the camera to the player we are spectating;
transform.parent = _playerSpectating?.PlayerBones.Head.Original;
- transform.localPosition = new Vector3(-0.05f, 0.17f, -0.5f);
+ transform.localPosition = new Vector3(-0.05f, 0.17f, -0.05f);
transform.localEulerAngles = new Vector3(260, 80, 0);
_isSpectatingPlayer = true;
}
From c547bdd8d985e5e490cd8b219f9bcc9f954bcac2 Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Sun, 26 May 2024 12:29:55 +0100
Subject: [PATCH 4/6] clean up some bits
---
Source/Coop/FreeCamera/FreeCamera.cs | 50 +++++++++---------
.../Coop/FreeCamera/FreeCameraController.cs | 51 ++++++++++++-------
2 files changed, 60 insertions(+), 41 deletions(-)
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index c705e8e14..199faf5e1 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -21,8 +21,9 @@ public class FreeCamera : MonoBehaviour
{
private CoopPlayer? _playerSpectating;
private bool _isSpectatingPlayer = false;
+ private bool _isUpdatingPlayerSpectate = false;
- public bool IsActive = false;
+ public bool IsActive { get; set; } = false;
private void StopSpectatingPlayer()
{
@@ -30,11 +31,11 @@ private void StopSpectatingPlayer()
{
_playerSpectating = null;
}
- if (_isSpectatingPlayer)
+ if (transform.parent != null)
{
- _isSpectatingPlayer = false;
+ transform.parent = null;
}
- transform.parent = null;
+ _isSpectatingPlayer = false;
}
private void SpectateNextPlayer()
@@ -52,7 +53,13 @@ private void SpectatePreviousPlayer()
///
/// True for the next player and false for the previous player
private void UpdatePlayerSpectator(bool nextPlayer)
- {
+ {
+ if (_isUpdatingPlayerSpectate)
+ {
+ return;
+ }
+ _isUpdatingPlayerSpectate = true;
+
SITGameComponent coopGameComponent = SITGameComponent.GetCoopGameComponent();
List players = [.. coopGameComponent
.Players
@@ -71,40 +78,35 @@ private void UpdatePlayerSpectator(bool nextPlayer)
}
else
{
- // We want to look for the next player
+ int playerIndex = 0;
if (nextPlayer)
{
- int playerIndex = players.IndexOf(_playerSpectating) + 1;
- if (players.Count - 1 >= playerIndex)
+ // We want to look for the next player in the list
+ playerIndex = players.IndexOf(_playerSpectating) + 1;
+ if (playerIndex > players.Count - 1)
{
- _playerSpectating = players[playerIndex];
- }
- else
- {
- _playerSpectating = players[0];
+ playerIndex = 0;
}
}
- // We are going backwards looking for the previous player
else
{
- int playerIndex = players.IndexOf(_playerSpectating) - 1;
- if (playerIndex >= 0)
- {
- _playerSpectating = players[playerIndex];
- }
- else
+ // We want to find the previous player
+ playerIndex = players.IndexOf(_playerSpectating) - 1;
+ if (playerIndex < 0)
{
- _playerSpectating = players[players.Count - 1];
+ playerIndex = players.Count - 1;
}
}
-
+
+ // Update the player we are spectating
+ _playerSpectating = players[playerIndex];
}
if (_playerSpectating != null)
{
// Attach the camera to the player we are spectating;
transform.parent = _playerSpectating?.PlayerBones.Head.Original;
- transform.localPosition = new Vector3(-0.05f, 0.17f, -0.05f);
+ transform.localPosition = new Vector3(-0.02f, 0.16f, -0.04f);
transform.localEulerAngles = new Vector3(260, 80, 0);
_isSpectatingPlayer = true;
}
@@ -113,6 +115,8 @@ private void UpdatePlayerSpectator(bool nextPlayer)
{
StopSpectatingPlayer();
}
+
+ _isUpdatingPlayerSpectate = false;
}
private void MoveAndRotateCamera()
diff --git a/Source/Coop/FreeCamera/FreeCameraController.cs b/Source/Coop/FreeCamera/FreeCameraController.cs
index e0f0126c4..eaac61653 100644
--- a/Source/Coop/FreeCamera/FreeCameraController.cs
+++ b/Source/Coop/FreeCamera/FreeCameraController.cs
@@ -1,4 +1,6 @@
-using BepInEx.Logging;
+#nullable enable
+
+using BepInEx.Logging;
using BSG.CameraEffects;
using Comfort.Common;
using EFT;
@@ -22,21 +24,20 @@ namespace StayInTarkov.Coop.FreeCamera
public class FreeCameraController : MonoBehaviour
{
- //private GameObject _mainCamera;
- private FreeCamera _freeCamScript;
+ private FreeCamera? _freeCamScript;
- private BattleUIScreen _playerUi;
+ private BattleUIScreen? _playerUi;
private bool _uiHidden;
- private GamePlayerOwner _gamePlayerOwner;
+ private GamePlayerOwner? _gamePlayerOwner;
private DateTime _lastTime = DateTime.MinValue;
private ManualLogSource Logger { get; } = BepInEx.Logging.Logger.CreateLogSource("FreeCameraController");
private CoopPlayer Player => (CoopPlayer) Singleton.Instance.MainPlayer;
- public GameObject CameraParent { get; set; }
- public Camera CameraFreeCamera { get; private set; }
- public Camera CameraMain { get; private set; }
+ public GameObject? CameraParent { get; set; }
+ public Camera? CameraFreeCamera { get; private set; }
+ public Camera? CameraMain { get; private set; }
protected void Awake()
{
@@ -62,7 +63,7 @@ public void Start()
}
// Get GamePlayerOwner component
- _gamePlayerOwner = GetLocalPlayerFromWorld().GetComponentInChildren();
+ _gamePlayerOwner = GetLocalPlayerFromWorld()?.GetComponentInChildren();
if (_gamePlayerOwner == null)
{
return;
@@ -73,7 +74,7 @@ public void Start()
private IEnumerator PlayerDeathRoutine()
{
- yield return new WaitForSeconds(PluginConfigSettings.Instance.CoopSettings.BlackScreenOnDeathTime);
+ yield return new WaitForSeconds(PluginConfigSettings.Instance?.CoopSettings.BlackScreenOnDeathTime ?? 5);
var fpsCamInstance = CameraClass.Instance;
if (fpsCamInstance == null)
@@ -139,13 +140,13 @@ public void Update()
if (!SITGameComponent.TryGetCoopGameComponent(out SITGameComponent coopGC))
return;
- CoopSITGame coopGame = coopGC.LocalGameInstance as CoopSITGame;
+ CoopSITGame coopGame = (CoopSITGame) coopGC.LocalGameInstance;
if (coopGame == null)
return;
var quitState = coopGC.GetQuitState();
if (Player.PlayerHealthController.IsAlive &&
- (Input.GetKey(KeyCode.F9) || (quitState != SITGameComponent.EQuitState.NONE && !_freeCamScript.IsActive)) &&
+ (Input.GetKey(KeyCode.F9) || (quitState != SITGameComponent.EQuitState.NONE && _freeCamScript?.IsActive == false)) &&
_lastTime < DateTime.Now.AddSeconds(-3))
{
_lastTime = DateTime.Now;
@@ -163,7 +164,7 @@ public void ToggleCamera()
if (Player == null)
return;
- if (!_freeCamScript.IsActive)
+ if (_freeCamScript?.IsActive == false)
{
GameObject[] allGameObject = Resources.FindObjectsOfTypeAll();
foreach (GameObject gobj in allGameObject)
@@ -225,8 +226,14 @@ private void SetPlayerToFreecamMode(EFT.Player localPlayer)
localPlayer.GetComponent().UpdatePointOfView();
}
- _gamePlayerOwner.enabled = false;
- _freeCamScript.IsActive = true;
+ if (_gamePlayerOwner != null)
+ {
+ _gamePlayerOwner.enabled = false;
+ }
+ if (_freeCamScript != null)
+ {
+ _freeCamScript.IsActive = true;
+ }
}
///
@@ -235,10 +242,16 @@ private void SetPlayerToFreecamMode(EFT.Player localPlayer)
///
private void SetPlayerToFirstPersonMode(EFT.Player localPlayer)
{
- _freeCamScript.IsActive = false;
+ if (_freeCamScript != null)
+ {
+ _freeCamScript.IsActive = true;
+ }
// re-enable _gamePlayerOwner
- _gamePlayerOwner.enabled = true;
+ if (_gamePlayerOwner != null)
+ {
+ _gamePlayerOwner.enabled = false;
+ }
localPlayer.PointOfView = EPointOfView.FirstPerson;
CameraClass.Instance.SetOcclusionCullingEnabled(true);
@@ -249,12 +262,14 @@ private void SetPlayerToFirstPersonMode(EFT.Player localPlayer)
/// Gets the current instance if it's available
///
/// Local instance; returns null if the game is not in raid
- private EFT.Player GetLocalPlayerFromWorld()
+ private EFT.Player? GetLocalPlayerFromWorld()
{
// If the GameWorld instance is null or has no RegisteredPlayers, it most likely means we're not in a raid
GameWorld gameWorld = Singleton.Instance;
if (gameWorld == null || gameWorld.MainPlayer == null)
+ {
return null;
+ }
// One of the RegisteredPlayers will have the IsYourPlayer flag set, which will be our own Player instance
return gameWorld.MainPlayer;
From 7f83b7bbe2a0a93a3e7fcc2d399b77f60cf4fb35 Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Thu, 30 May 2024 22:40:47 +0100
Subject: [PATCH 5/6] Improve switching camera and move the camera to possibly
the shoulder
---
Source/Coop/FreeCamera/FreeCamera.cs | 46 ++++++++++++++++++----------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index 199faf5e1..1735052b4 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -21,7 +21,7 @@ public class FreeCamera : MonoBehaviour
{
private CoopPlayer? _playerSpectating;
private bool _isSpectatingPlayer = false;
- private bool _isUpdatingPlayerSpectate = false;
+ private bool _spectateRightShoulder = true;
public bool IsActive { get; set; } = false;
@@ -53,13 +53,7 @@ private void SpectatePreviousPlayer()
///
/// True for the next player and false for the previous player
private void UpdatePlayerSpectator(bool nextPlayer)
- {
- if (_isUpdatingPlayerSpectate)
- {
- return;
- }
- _isUpdatingPlayerSpectate = true;
-
+ {
SITGameComponent coopGameComponent = SITGameComponent.GetCoopGameComponent();
List players = [.. coopGameComponent
.Players
@@ -104,19 +98,17 @@ private void UpdatePlayerSpectator(bool nextPlayer)
if (_playerSpectating != null)
{
+ _isSpectatingPlayer = true;
+
// Attach the camera to the player we are spectating;
transform.parent = _playerSpectating?.PlayerBones.Head.Original;
- transform.localPosition = new Vector3(-0.02f, 0.16f, -0.04f);
- transform.localEulerAngles = new Vector3(260, 80, 0);
- _isSpectatingPlayer = true;
+ SetPlayerSpectateShoulder();
}
}
else
{
StopSpectatingPlayer();
}
-
- _isUpdatingPlayerSpectate = false;
}
private void MoveAndRotateCamera()
@@ -177,6 +169,23 @@ private void MoveAndRotateCamera()
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
}
+ private void SetPlayerSpectateShoulder()
+ {
+ if (_isSpectatingPlayer)
+ {
+ if (_spectateRightShoulder)
+ {
+ transform.localEulerAngles = new Vector3(240, 80, 0);
+ transform.localPosition = new Vector3(0.24f, 0.12f, -0.16f);
+ }
+ else
+ {
+ transform.localEulerAngles = new Vector3(240, 80, 0);
+ transform.localPosition = new Vector3(0.24f, 0.12f, 0.16f);
+ }
+ }
+ }
+
protected void OnDestroy()
{
Destroy(this);
@@ -190,20 +199,25 @@ protected void Update()
}
// Spectate the next player
- if (Input.GetKey(KeyCode.Mouse0))
+ if (Input.GetKeyDown(KeyCode.Mouse0))
{
SpectateNextPlayer();
}
// Spectate the previous player
- else if (Input.GetKey(KeyCode.Mouse1))
+ else if (Input.GetKeyDown(KeyCode.Mouse1))
{
SpectatePreviousPlayer();
}
// Stop following the currently selected player
- else if (Input.GetKey(KeyCode.End))
+ else if (Input.GetKeyDown(KeyCode.End))
{
StopSpectatingPlayer();
}
+ else if (Input.GetKeyDown(KeyCode.Home))
+ {
+ _spectateRightShoulder = !_spectateRightShoulder;
+ SetPlayerSpectateShoulder();
+ }
// If we aren't spectating anyone then just update the camera normally
if (!_isSpectatingPlayer)
From 395909ccdff5430f3010b12882ebcd4ed049a5e0 Mon Sep 17 00:00:00 2001
From: artehe <112902041+artehe@users.noreply.github.com>
Date: Fri, 31 May 2024 10:18:26 +0100
Subject: [PATCH 6/6] update camera positions better
---
Source/Coop/FreeCamera/FreeCamera.cs | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/Source/Coop/FreeCamera/FreeCamera.cs b/Source/Coop/FreeCamera/FreeCamera.cs
index 1735052b4..8c32df980 100644
--- a/Source/Coop/FreeCamera/FreeCamera.cs
+++ b/Source/Coop/FreeCamera/FreeCamera.cs
@@ -101,7 +101,6 @@ private void UpdatePlayerSpectator(bool nextPlayer)
_isSpectatingPlayer = true;
// Attach the camera to the player we are spectating;
- transform.parent = _playerSpectating?.PlayerBones.Head.Original;
SetPlayerSpectateShoulder();
}
}
@@ -175,13 +174,15 @@ private void SetPlayerSpectateShoulder()
{
if (_spectateRightShoulder)
{
- transform.localEulerAngles = new Vector3(240, 80, 0);
- transform.localPosition = new Vector3(0.24f, 0.12f, -0.16f);
+ transform.parent = _playerSpectating?.PlayerBones.RightShoulder.Original;
+ transform.localEulerAngles = new Vector3(250, 270, 270);
+ transform.localPosition = new Vector3(-0.12f, 0.04f, 0.16f);
}
else
{
- transform.localEulerAngles = new Vector3(240, 80, 0);
- transform.localPosition = new Vector3(0.24f, 0.12f, 0.16f);
+ transform.parent = _playerSpectating?.PlayerBones.LeftShoulder.Original;
+ transform.localEulerAngles = new Vector3(250, 90, 270);
+ transform.localPosition = new Vector3(-0.12f, -0.04f, -0.16f);
}
}
}