786 lines
22 KiB
C#
786 lines
22 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using JetBrains.Annotations;
|
|
using RoR2.CameraModes;
|
|
using RoR2.ConVar;
|
|
using RoR2.Networking;
|
|
using RoR2.UI;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.PostProcessing;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
namespace RoR2;
|
|
|
|
public class CameraRigController : MonoBehaviour
|
|
{
|
|
[Obsolete("CameraMode objects are now used instead of enums.", true)]
|
|
public enum CameraMode
|
|
{
|
|
None,
|
|
PlayerBasic,
|
|
Fly,
|
|
SpectateOrbit,
|
|
SpectateUser
|
|
}
|
|
|
|
public struct AimAssistInfo
|
|
{
|
|
public HurtBox aimAssistHurtbox;
|
|
|
|
public Vector3 localPositionOnHurtbox;
|
|
|
|
public Vector3 worldPosition;
|
|
}
|
|
|
|
[Tooltip("The main camera for rendering the scene.")]
|
|
[Header("Component References")]
|
|
public Camera sceneCam;
|
|
|
|
[Tooltip("The UI camera.")]
|
|
public Camera uiCam;
|
|
|
|
[Tooltip("The skybox camera.")]
|
|
public Camera skyboxCam;
|
|
|
|
[Tooltip("The particle system to play while sprinting.")]
|
|
public ParticleSystem sprintingParticleSystem;
|
|
|
|
[Tooltip("The particle system to play while skills are disabled.")]
|
|
public ParticleSystem disabledSkillsParticleSystem;
|
|
|
|
[Header("Camera Parameters")]
|
|
[Tooltip("The default FOV of this camera.")]
|
|
public float baseFov = 60f;
|
|
|
|
[Tooltip("The viewport to use.")]
|
|
public Rect viewport = new Rect(0f, 0f, 1f, 1f);
|
|
|
|
[Tooltip("The maximum distance of the raycast used to determine the aim vector.")]
|
|
public float maxAimRaycastDistance = 1000f;
|
|
|
|
[Tooltip("If true, treat this camera as though it's in a cutscene")]
|
|
public bool isCutscene;
|
|
|
|
[Header("Near-Camera Character Dithering")]
|
|
public bool enableFading = true;
|
|
|
|
public float fadeStartDistance = 1f;
|
|
|
|
public float fadeEndDistance = 4f;
|
|
|
|
[Header("Behavior")]
|
|
[Tooltip("Whether or not to create a HUD.")]
|
|
public bool createHud = true;
|
|
|
|
[Tooltip("Whether or not this camera being enabled forces player-owned cameras to be disabled.")]
|
|
public bool suppressPlayerCameras;
|
|
|
|
[Tooltip("Forces music to be enabled for this camera.")]
|
|
public bool enableMusic;
|
|
|
|
private ulong musicListenerId;
|
|
|
|
private bool musicEnabled;
|
|
|
|
[Header("Target (for debug only)")]
|
|
public GameObject nextTarget;
|
|
|
|
public static Action OnChangeHUD;
|
|
|
|
public static Action OnHUDUpdated;
|
|
|
|
private CameraModeBase _cameraMode;
|
|
|
|
private GameObject _target;
|
|
|
|
private CameraState desiredCameraState;
|
|
|
|
public CameraState currentCameraState;
|
|
|
|
public bool doNotOverrideCameraState;
|
|
|
|
private CameraState lerpCameraState;
|
|
|
|
private float lerpCameraTime = 1f;
|
|
|
|
private float lerpCameraTimeScale = 1f;
|
|
|
|
private ICameraStateProvider overrideCam;
|
|
|
|
private CameraModeBase.CameraModeContext cameraModeContext;
|
|
|
|
private NetworkUser _viewer;
|
|
|
|
private LocalUser _localUserViewer;
|
|
|
|
private static GameObject DamageNumberManagerPrefab;
|
|
|
|
private static GameObject HudPrefab;
|
|
|
|
private static string previousHudPath;
|
|
|
|
public CameraTargetParams targetParams;
|
|
|
|
private const string musicSystemDeviceShareSet = "Music_Audio_Device";
|
|
|
|
public AimAssistInfo lastAimAssist;
|
|
|
|
public AimAssistInfo aimAssist;
|
|
|
|
private static List<CameraRigController> instancesList = new List<CameraRigController>();
|
|
|
|
public static readonly ReadOnlyCollection<CameraRigController> readOnlyInstancesList = instancesList.AsReadOnly();
|
|
|
|
public static FloatConVar aimStickExponent = new FloatConVar("aim_stick_exponent", ConVarFlags.None, "1", "The exponent for stick input used for aiming.");
|
|
|
|
public static FloatConVar aimStickDualZoneThreshold = new FloatConVar("aim_stick_dual_zone_threshold", ConVarFlags.None, "0.90", "The threshold for stick dual zone behavior.");
|
|
|
|
public static FloatConVar aimStickDualZoneSlope = new FloatConVar("aim_stick_dual_zone_slope", ConVarFlags.None, "0.40", "The slope value for stick dual zone behavior.");
|
|
|
|
public static FloatConVar aimStickDualZoneSmoothing = new FloatConVar("aim_stick_smoothing", ConVarFlags.None, "0.05", "The smoothing value for stick aiming.");
|
|
|
|
public static FloatConVar aimStickGlobalScale = new FloatConVar("aim_stick_global_scale", ConVarFlags.Archive, "1.00", "The global sensitivity scale for stick aiming.");
|
|
|
|
public static FloatConVar aimStickAssistMinSlowdownScale = new FloatConVar("aim_stick_assist_min_slowdown_scale", ConVarFlags.None, "1", "The MIN amount the sensitivity scales down when passing over an enemy.");
|
|
|
|
public static FloatConVar aimStickAssistMaxSlowdownScale = new FloatConVar("aim_stick_assist_max_slowdown_scale", ConVarFlags.None, "0.4", "The MAX amount the sensitivity scales down when passing over an enemy. UNUSED");
|
|
|
|
public static FloatConVar aimStickAssistMinDelta = new FloatConVar("aim_stick_assist_min_delta", ConVarFlags.None, "0", "The MIN amount in radians the aim assist will turn towards");
|
|
|
|
public static FloatConVar aimStickAssistMaxDelta = new FloatConVar("aim_stick_assist_max_delta", ConVarFlags.None, "1.57", "The MAX amount in radians the aim assist will turn towards");
|
|
|
|
public static FloatConVar aimStickAssistMaxInputHelp = new FloatConVar("aim_stick_assist_max_input_help", ConVarFlags.None, "0.2", "The amount, from 0-1, that the aim assist will actually ADD magnitude towards. Helps you keep target while strafing. CURRENTLY UNUSED.");
|
|
|
|
public static FloatConVar aimStickAssistMaxSize = new FloatConVar("aim_stick_assist_max_size", ConVarFlags.None, "3", "The size, as a coefficient, of the aim assist 'white' zone.");
|
|
|
|
public static FloatConVar aimStickAssistMinSize = new FloatConVar("aim_stick_assist_min_size", ConVarFlags.None, "1", "The minimum size, as a percentage of the GUI, of the aim assist 'red' zone.");
|
|
|
|
public static BoolConVar enableSprintSensitivitySlowdown = new BoolConVar("enable_sprint_sensitivity_slowdown", ConVarFlags.Archive, "1", "Enables sensitivity reduction while sprinting.");
|
|
|
|
private float hitmarkerAlpha;
|
|
|
|
private float hitmarkerTimer;
|
|
|
|
public bool disableSpectating { get; set; }
|
|
|
|
public CameraModeBase cameraMode
|
|
{
|
|
get
|
|
{
|
|
return _cameraMode;
|
|
}
|
|
set
|
|
{
|
|
if (_cameraMode != value)
|
|
{
|
|
_cameraMode?.OnUninstall(this);
|
|
_cameraMode = value;
|
|
_cameraMode?.OnInstall(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
public HUD hud { get; private set; }
|
|
|
|
public GameObject firstPersonTarget { get; private set; }
|
|
|
|
public TeamIndex targetTeamIndex { get; private set; } = TeamIndex.None;
|
|
|
|
|
|
public CharacterBody targetBody { get; private set; }
|
|
|
|
public Vector3 rawScreenShakeDisplacement { get; private set; }
|
|
|
|
public Vector3 crosshairWorldPosition { get; private set; }
|
|
|
|
public bool hasOverride => overrideCam != null;
|
|
|
|
public bool isControlAllowed
|
|
{
|
|
get
|
|
{
|
|
if (hasOverride)
|
|
{
|
|
return overrideCam.IsUserControlAllowed(this);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public bool isHudAllowed
|
|
{
|
|
get
|
|
{
|
|
if ((bool)target)
|
|
{
|
|
if (hasOverride)
|
|
{
|
|
return overrideCam.IsHudAllowed(this);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public GameObject target
|
|
{
|
|
get
|
|
{
|
|
return _target;
|
|
}
|
|
private set
|
|
{
|
|
if ((object)_target != value)
|
|
{
|
|
GameObject oldTarget = _target;
|
|
_target = value;
|
|
bool flag = _target;
|
|
targetParams = (flag ? target.GetComponent<CameraTargetParams>() : null);
|
|
targetBody = (flag ? target.GetComponent<CharacterBody>() : null);
|
|
cameraMode?.OnTargetChanged(this, new CameraModeBase.OnTargetChangedArgs
|
|
{
|
|
oldTarget = oldTarget,
|
|
newTarget = _target
|
|
});
|
|
CameraRigController.onCameraTargetChanged?.Invoke(this, target);
|
|
}
|
|
}
|
|
}
|
|
|
|
public NetworkUser viewer
|
|
{
|
|
get
|
|
{
|
|
return _viewer;
|
|
}
|
|
set
|
|
{
|
|
_viewer = value;
|
|
localUserViewer = (_viewer ? _viewer.localUser : null);
|
|
}
|
|
}
|
|
|
|
public LocalUser localUserViewer
|
|
{
|
|
get
|
|
{
|
|
return _localUserViewer;
|
|
}
|
|
private set
|
|
{
|
|
if (_localUserViewer != value)
|
|
{
|
|
if (_localUserViewer != null)
|
|
{
|
|
_localUserViewer.cameraRigController = null;
|
|
}
|
|
_localUserViewer = value;
|
|
if (_localUserViewer != null)
|
|
{
|
|
_localUserViewer.cameraRigController = this;
|
|
}
|
|
if ((bool)hud)
|
|
{
|
|
hud.localUserViewer = _localUserViewer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public HurtBox lastCrosshairHurtBox { get; private set; }
|
|
|
|
public static event Action<CameraRigController, GameObject> onCameraTargetChanged;
|
|
|
|
public static event Action<CameraRigController> onCameraEnableGlobal;
|
|
|
|
public static event Action<CameraRigController> onCameraDisableGlobal;
|
|
|
|
private void StartStateLerp(float lerpDuration)
|
|
{
|
|
lerpCameraState = currentCameraState;
|
|
if (lerpDuration > 0f)
|
|
{
|
|
lerpCameraTime = 0f;
|
|
lerpCameraTimeScale = 1f / lerpDuration;
|
|
}
|
|
else
|
|
{
|
|
lerpCameraTime = 1f;
|
|
lerpCameraTimeScale = 0f;
|
|
}
|
|
}
|
|
|
|
public void SetOverrideCam(ICameraStateProvider newOverrideCam, float lerpDuration = 1f)
|
|
{
|
|
if (newOverrideCam != overrideCam)
|
|
{
|
|
if (overrideCam != null && newOverrideCam == null)
|
|
{
|
|
cameraMode?.MatchState(in cameraModeContext, in currentCameraState);
|
|
}
|
|
overrideCam = newOverrideCam;
|
|
StartStateLerp(lerpDuration);
|
|
}
|
|
}
|
|
|
|
public bool IsOverrideCam(ICameraStateProvider testOverrideCam)
|
|
{
|
|
return overrideCam == testOverrideCam;
|
|
}
|
|
|
|
public static IEnumerator InitializeReferences()
|
|
{
|
|
AsyncOperationHandle<GameObject> handle2 = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/DamageNumberManager");
|
|
while (!handle2.IsDone)
|
|
{
|
|
yield return null;
|
|
}
|
|
DamageNumberManagerPrefab = handle2.Result;
|
|
previousHudPath = GetHUDPath();
|
|
handle2 = LegacyResourcesAPI.LoadAsync<GameObject>(previousHudPath);
|
|
while (!handle2.IsDone)
|
|
{
|
|
yield return null;
|
|
}
|
|
HudPrefab = handle2.Result;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
RoR2Application.onUpdate += EarlyUpdate;
|
|
OnChangeHUD = (Action)Delegate.Combine(OnChangeHUD, new Action(UpdateHUD));
|
|
UpdateHUD();
|
|
if ((bool)uiCam)
|
|
{
|
|
uiCam.transform.parent = null;
|
|
uiCam.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
|
}
|
|
if (!DamageNumberManager.instance)
|
|
{
|
|
if (DamageNumberManagerPrefab != null)
|
|
{
|
|
UnityEngine.Object.Instantiate(DamageNumberManagerPrefab);
|
|
}
|
|
else
|
|
{
|
|
AsyncOperationHandle<GameObject> asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/DamageNumberManager");
|
|
asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
|
|
{
|
|
UnityEngine.Object.Instantiate(x.Result);
|
|
};
|
|
}
|
|
}
|
|
currentCameraState = new CameraState
|
|
{
|
|
position = base.transform.position,
|
|
rotation = base.transform.rotation,
|
|
fov = baseFov
|
|
};
|
|
cameraMode = CameraModePlayerBasic.playerBasic;
|
|
if (enableMusic && (!RoR2Application.isInLocalMultiPlayer || _viewer.localUser.inputPlayer.name == "PlayerMain"))
|
|
{
|
|
EnableMusicForCamera();
|
|
}
|
|
}
|
|
|
|
private void UpdateHUD()
|
|
{
|
|
if (createHud)
|
|
{
|
|
if ((bool)hud)
|
|
{
|
|
UnityEngine.Object.Destroy(hud.gameObject);
|
|
}
|
|
string hUDPath = GetHUDPath();
|
|
if (HudPrefab == null || hUDPath != previousHudPath)
|
|
{
|
|
HudPrefab = LegacyResourcesAPI.Load<GameObject>(hUDPath);
|
|
previousHudPath = hUDPath;
|
|
}
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(HudPrefab);
|
|
hud = gameObject.GetComponent<HUD>();
|
|
hud.cameraRigController = this;
|
|
SetPostProcessVolumeExclusive(hud.scoreboardPostProcessVolume);
|
|
hud.GetComponent<Canvas>().worldCamera = uiCam;
|
|
hud.GetComponent<CrosshairManager>().cameraRigController = this;
|
|
hud.localUserViewer = localUserViewer;
|
|
OnHUDUpdated?.Invoke();
|
|
}
|
|
}
|
|
|
|
[CanBeNull]
|
|
private static string GetHUDPath()
|
|
{
|
|
if (NetworkUser.readOnlyLocalPlayersList == null || NetworkUser.readOnlyLocalPlayersList.Count < 1)
|
|
{
|
|
return "Prefabs/HUDSimple";
|
|
}
|
|
UserProfile userProfile = NetworkUser.readOnlyLocalPlayersList[0]?.localUser?.userProfile;
|
|
if (userProfile != null)
|
|
{
|
|
switch ((HudType)userProfile.hudSizeMode)
|
|
{
|
|
case HudType.Default:
|
|
return "Prefabs/HUDSimple";
|
|
case HudType.Large:
|
|
return "Prefabs/HUDSimple_Big";
|
|
case HudType.Auto:
|
|
return "Prefabs/HUDSimple_Big";
|
|
default:
|
|
Debug.LogWarning(string.Format("Undefined {0}. Value : {1}. Resorting to default HUD.", "HudType", userProfile.hudSizeMode));
|
|
return "Prefabs/HUDSimple";
|
|
}
|
|
}
|
|
return "Prefabs/HUDSimple";
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
instancesList.Add(this);
|
|
if ((bool)uiCam)
|
|
{
|
|
uiCam.gameObject.SetActive(value: true);
|
|
}
|
|
if ((bool)hud)
|
|
{
|
|
hud.gameObject.SetActive(value: true);
|
|
}
|
|
CameraRigController.onCameraEnableGlobal?.Invoke(this);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
CameraRigController.onCameraDisableGlobal?.Invoke(this);
|
|
if ((bool)uiCam)
|
|
{
|
|
uiCam.gameObject.SetActive(value: false);
|
|
}
|
|
if ((bool)hud)
|
|
{
|
|
hud.gameObject.SetActive(value: false);
|
|
}
|
|
instancesList.Remove(this);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
RoR2Application.onUpdate -= EarlyUpdate;
|
|
OnChangeHUD = (Action)Delegate.Remove(OnChangeHUD, new Action(UpdateHUD));
|
|
cameraMode = null;
|
|
if ((bool)uiCam)
|
|
{
|
|
UnityEngine.Object.Destroy(uiCam.gameObject);
|
|
}
|
|
if ((bool)hud)
|
|
{
|
|
UnityEngine.Object.Destroy(hud.gameObject);
|
|
}
|
|
DisableMusicForCamera();
|
|
}
|
|
|
|
private void EarlyUpdate()
|
|
{
|
|
target = nextTarget;
|
|
if ((bool)targetBody)
|
|
{
|
|
targetTeamIndex = targetBody.teamComponent.teamIndex;
|
|
}
|
|
if (Time.deltaTime != 0f && !isCutscene)
|
|
{
|
|
lerpCameraTime += Time.deltaTime * lerpCameraTimeScale;
|
|
firstPersonTarget = null;
|
|
sceneCam.rect = viewport;
|
|
GenerateCameraModeContext(out cameraModeContext);
|
|
if (cameraMode != null)
|
|
{
|
|
cameraMode.CollectLookInput(in cameraModeContext, out var result);
|
|
CameraModeBase cameraModeBase = cameraMode;
|
|
ref CameraModeBase.CameraModeContext context = ref cameraModeContext;
|
|
CameraModeBase.ApplyLookInputArgs args = new CameraModeBase.ApplyLookInputArgs
|
|
{
|
|
lookInput = result.lookInput
|
|
};
|
|
cameraModeBase.ApplyLookInput(in context, in args);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (Time.deltaTime == 0f || isCutscene)
|
|
{
|
|
return;
|
|
}
|
|
CameraState cameraState = currentCameraState;
|
|
if (cameraMode != null && cameraModeContext.cameraInfo.cameraRigController != null && !doNotOverrideCameraState)
|
|
{
|
|
cameraMode.Update(in cameraModeContext, out var result);
|
|
cameraState = result.cameraState;
|
|
firstPersonTarget = result.firstPersonTarget;
|
|
crosshairWorldPosition = result.crosshairWorldPosition;
|
|
SetParticleSystemActive(result.showSprintParticles, sprintingParticleSystem);
|
|
SetParticleSystemActive(result.showDisabledSkillsParticles, disabledSkillsParticleSystem);
|
|
}
|
|
if ((bool)hud)
|
|
{
|
|
CharacterMaster targetMaster = (targetBody ? targetBody.master : null);
|
|
hud.targetMaster = targetMaster;
|
|
}
|
|
CameraState cameraState2 = cameraState;
|
|
if (overrideCam != null)
|
|
{
|
|
if (!(overrideCam is UnityEngine.Object @object) || (bool)@object)
|
|
{
|
|
overrideCam.GetCameraState(this, ref cameraState2);
|
|
}
|
|
else
|
|
{
|
|
overrideCam = null;
|
|
}
|
|
}
|
|
if (lerpCameraTime >= 1f)
|
|
{
|
|
currentCameraState = cameraState2;
|
|
}
|
|
else
|
|
{
|
|
currentCameraState = CameraState.Lerp(ref lerpCameraState, ref cameraState2, RemapLerpTime(lerpCameraTime));
|
|
}
|
|
SetCameraState(currentCameraState);
|
|
}
|
|
|
|
public void UpdatePreviousCameraState(Vector3 position, Quaternion rotation)
|
|
{
|
|
cameraModeContext.cameraInfo.previousCameraState.position = position;
|
|
cameraModeContext.cameraInfo.previousCameraState.rotation = rotation;
|
|
}
|
|
|
|
private void GenerateCameraModeContext(out CameraModeBase.CameraModeContext result)
|
|
{
|
|
result.cameraInfo = default(CameraModeBase.CameraInfo);
|
|
result.targetInfo = default(CameraModeBase.TargetInfo);
|
|
result.viewerInfo = default(CameraModeBase.ViewerInfo);
|
|
ref CameraModeBase.CameraInfo cameraInfo = ref result.cameraInfo;
|
|
ref CameraModeBase.TargetInfo targetInfo = ref result.targetInfo;
|
|
ref CameraModeBase.ViewerInfo viewerInfo = ref result.viewerInfo;
|
|
cameraInfo.cameraRigController = this;
|
|
cameraInfo.sceneCam = sceneCam;
|
|
cameraInfo.overrideCam = overrideCam;
|
|
cameraInfo.previousCameraState = currentCameraState;
|
|
cameraInfo.baseFov = baseFov;
|
|
targetInfo.target = (target ? target : null);
|
|
targetInfo.body = targetBody;
|
|
targetInfo.inputBank = targetInfo.target?.GetComponent<InputBankTest>();
|
|
if (targetBody != null && targetBody.currentVehicle != null && targetBody.currentVehicle.targetParams != null)
|
|
{
|
|
targetInfo.targetParams = targetBody.currentVehicle.targetParams;
|
|
}
|
|
else
|
|
{
|
|
targetInfo.targetParams = targetParams;
|
|
}
|
|
targetInfo.teamIndex = targetInfo.target?.GetComponent<TeamComponent>()?.teamIndex ?? TeamIndex.None;
|
|
targetInfo.isSprinting = (bool)targetInfo.body && targetInfo.body.isSprinting;
|
|
targetInfo.skillsAreDisabled = (bool)targetInfo.body && targetInfo.body.allSkillsDisabled;
|
|
targetInfo.master = targetInfo.body?.master;
|
|
targetInfo.networkUser = targetInfo.master?.playerCharacterMasterController?.networkUser;
|
|
targetInfo.networkedViewAngles = targetInfo.networkUser?.GetComponent<NetworkedViewAngles>();
|
|
targetInfo.isViewerControlled = (bool)targetInfo.networkUser && (object)targetInfo.networkUser == localUserViewer?.currentNetworkUser;
|
|
viewerInfo.localUser = localUserViewer;
|
|
viewerInfo.userProfile = localUserViewer?.userProfile;
|
|
viewerInfo.inputPlayer = localUserViewer?.inputPlayer;
|
|
viewerInfo.eventSystem = localUserViewer?.eventSystem;
|
|
viewerInfo.hasCursor = (bool)viewerInfo.eventSystem && viewerInfo.eventSystem.isCursorVisible;
|
|
viewerInfo.isUIFocused = localUserViewer?.isUIFocused ?? false;
|
|
}
|
|
|
|
public void CloneCameraContext(CameraRigController cloneThisCamera)
|
|
{
|
|
if (!(cloneThisCamera == null))
|
|
{
|
|
cameraModeContext = cloneThisCamera.cameraModeContext;
|
|
}
|
|
}
|
|
|
|
public float Raycast(Ray ray, float maxDistance, float wallCushion)
|
|
{
|
|
int num = 0;
|
|
num = HGPhysics.SphereCastAll(out var hits, ray.origin, wallCushion, ray.direction, maxDistance, LayerIndex.world.mask, QueryTriggerInteraction.Ignore);
|
|
float num2 = maxDistance;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
float distance = hits[i].distance;
|
|
if (distance < num2)
|
|
{
|
|
Collider collider = hits[i].collider;
|
|
if ((bool)collider && !collider.GetComponent<NonSolidToCamera>())
|
|
{
|
|
num2 = distance;
|
|
}
|
|
}
|
|
}
|
|
HGPhysics.ReturnResults(hits);
|
|
return num2;
|
|
}
|
|
|
|
private static float RemapLerpTime(float t)
|
|
{
|
|
float num = 1f;
|
|
float num2 = 0f;
|
|
float num3 = 1f;
|
|
if ((t /= num / 2f) < 1f)
|
|
{
|
|
return num3 / 2f * t * t + num2;
|
|
}
|
|
return (0f - num3) / 2f * ((t -= 1f) * (t - 2f) - 1f) + num2;
|
|
}
|
|
|
|
public void SetCameraState(CameraState cameraState)
|
|
{
|
|
currentCameraState = cameraState;
|
|
float num = ((localUserViewer == null) ? 1f : localUserViewer.userProfile.screenShakeScale);
|
|
Vector3 position = cameraState.position;
|
|
rawScreenShakeDisplacement = ShakeEmitter.ComputeTotalShakeAtPoint(cameraState.position);
|
|
Vector3 vector = rawScreenShakeDisplacement * num;
|
|
Vector3 position2 = position + vector;
|
|
if (vector != Vector3.zero && Physics.SphereCast(position, direction: vector, radius: sceneCam.nearClipPlane, hitInfo: out var hitInfo, maxDistance: vector.magnitude, layerMask: LayerIndex.world.mask, queryTriggerInteraction: QueryTriggerInteraction.Ignore))
|
|
{
|
|
position2 = position + vector.normalized * hitInfo.distance;
|
|
}
|
|
base.transform.SetPositionAndRotation(position2, cameraState.rotation);
|
|
if ((bool)sceneCam)
|
|
{
|
|
sceneCam.fieldOfView = cameraState.fov;
|
|
}
|
|
}
|
|
|
|
public static Ray ModifyAimRayIfApplicable(Ray originalAimRay, GameObject target, out float extraRaycastDistance)
|
|
{
|
|
CameraRigController cameraRigController = null;
|
|
for (int i = 0; i < readOnlyInstancesList.Count; i++)
|
|
{
|
|
CameraRigController cameraRigController2 = readOnlyInstancesList[i];
|
|
if (cameraRigController2.target == target && cameraRigController2._localUserViewer.cachedBodyObject == target && !cameraRigController2.hasOverride)
|
|
{
|
|
cameraRigController = cameraRigController2;
|
|
break;
|
|
}
|
|
}
|
|
if ((bool)cameraRigController)
|
|
{
|
|
Camera camera = cameraRigController.sceneCam;
|
|
extraRaycastDistance = (originalAimRay.origin - camera.transform.position).magnitude;
|
|
return camera.ViewportPointToRay(new Vector2(0.5f, 0.5f));
|
|
}
|
|
extraRaycastDistance = 0f;
|
|
return originalAimRay;
|
|
}
|
|
|
|
private void SetSprintParticlesActive(bool newSprintParticlesActive)
|
|
{
|
|
if (!sprintingParticleSystem)
|
|
{
|
|
return;
|
|
}
|
|
ParticleSystem.MainModule main = sprintingParticleSystem.main;
|
|
if (newSprintParticlesActive)
|
|
{
|
|
main.loop = true;
|
|
if (!sprintingParticleSystem.isPlaying)
|
|
{
|
|
sprintingParticleSystem.Play();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
main.loop = false;
|
|
}
|
|
}
|
|
|
|
private void SetParticleSystemActive(bool newParticlesActive, ParticleSystem particleSystem)
|
|
{
|
|
if (!particleSystem)
|
|
{
|
|
return;
|
|
}
|
|
ParticleSystem.MainModule main = particleSystem.main;
|
|
if (newParticlesActive)
|
|
{
|
|
main.loop = true;
|
|
if (!particleSystem.isPlaying)
|
|
{
|
|
particleSystem.Play();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
main.loop = false;
|
|
}
|
|
}
|
|
|
|
public void SetPostProcessVolumeExclusive(PostProcessVolume volume)
|
|
{
|
|
if (!(volume == null) && !(sceneCam == null))
|
|
{
|
|
volume.targetLayer = sceneCam.GetComponent<PostProcessLayer>();
|
|
}
|
|
}
|
|
|
|
[InitDuringStartup]
|
|
private static void Init()
|
|
{
|
|
SceneCamera.onSceneCameraPreCull += delegate(SceneCamera sceneCam)
|
|
{
|
|
sceneCam.cameraRigController.sprintingParticleSystem.gameObject.layer = LayerIndex.defaultLayer.intVal;
|
|
};
|
|
SceneCamera.onSceneCameraPostRender += delegate(SceneCamera sceneCam)
|
|
{
|
|
sceneCam.cameraRigController.sprintingParticleSystem.gameObject.layer = LayerIndex.noDraw.intVal;
|
|
};
|
|
}
|
|
|
|
public static bool IsObjectSpectatedByAnyCamera(GameObject gameObject)
|
|
{
|
|
for (int i = 0; i < instancesList.Count; i++)
|
|
{
|
|
if (instancesList[i].target == gameObject)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
[ContextMenu("Print Debug Info")]
|
|
private void PrintDebugInfo()
|
|
{
|
|
Debug.LogFormat("hasOverride={0} overrideCam={1} isControlAllowed={2}", hasOverride, overrideCam, isControlAllowed);
|
|
}
|
|
|
|
public void EnableMusicForCamera(string deviceShareSet = "Music_Audio_Device")
|
|
{
|
|
GameObject gameObject = new GameObject("MusicListener", typeof(AkGameObj), typeof(AkAudioListener));
|
|
Transform obj = gameObject.transform;
|
|
obj.localPosition = Vector3.zero;
|
|
obj.localRotation = Quaternion.identity;
|
|
obj.localScale = Vector3.one;
|
|
obj.SetParent(sceneCam.transform, worldPositionStays: false);
|
|
AkOutputSettings in_Settings = new AkOutputSettings(deviceShareSet);
|
|
ulong[] array = new ulong[1] { AkSoundEngine.GetAkGameObjectID(gameObject) };
|
|
AkSoundEngine.AddOutput(in_Settings, out var out_pDeviceID, array, (uint)array.Length);
|
|
musicListenerId = out_pDeviceID;
|
|
musicEnabled = true;
|
|
}
|
|
|
|
public void DisableMusicForCamera()
|
|
{
|
|
if (musicEnabled)
|
|
{
|
|
AkSoundEngine.RemoveOutput(musicListenerId);
|
|
}
|
|
}
|
|
}
|