first commit
This commit is contained in:
@@ -0,0 +1,471 @@
|
||||
using System;
|
||||
using NitroxClient.GameLogic;
|
||||
using UnityEngine;
|
||||
using static PlayerCinematicController;
|
||||
|
||||
namespace NitroxClient.MonoBehaviours.CinematicController;
|
||||
|
||||
/// <summary>
|
||||
/// Override for <see cref="PlayerCinematicController"/>
|
||||
/// </summary>
|
||||
public class RemotePlayerCinematicController : MonoBehaviour, IManagedUpdateBehaviour, IManagedLateUpdateBehaviour
|
||||
{
|
||||
[AssertNotNull] public Transform animatedTransform;
|
||||
|
||||
public GameObject informGameObject;
|
||||
|
||||
public Transform endTransform;
|
||||
|
||||
public bool onlyUseEndTransformInVr;
|
||||
|
||||
public bool playInVr;
|
||||
|
||||
public string playerViewAnimationName = "";
|
||||
|
||||
public string playerViewInterpolateAnimParam = "";
|
||||
|
||||
public string animParam = "cinematicMode";
|
||||
|
||||
public string interpolateAnimParam = "";
|
||||
|
||||
public float interpolationTime = 0.25f;
|
||||
|
||||
public float interpolationTimeOut = 0.25f;
|
||||
|
||||
public string receiversAnimParam = "";
|
||||
|
||||
public GameObject[] animParamReceivers;
|
||||
|
||||
public bool interpolateDuringAnimation;
|
||||
|
||||
public bool debug;
|
||||
|
||||
public Animator animator;
|
||||
|
||||
[NonSerialized] public bool cinematicModeActive;
|
||||
|
||||
private Vector3 playerFromPosition = Vector3.zero;
|
||||
|
||||
private Quaternion playerFromRotation = Quaternion.identity;
|
||||
|
||||
private bool onCinematicModeEndCall;
|
||||
|
||||
private float timeStateChanged;
|
||||
|
||||
private State _state;
|
||||
|
||||
private RemotePlayer player;
|
||||
|
||||
private bool subscribed;
|
||||
|
||||
private bool _animState;
|
||||
|
||||
public static int cinematicModeCount { get; private set; }
|
||||
|
||||
public static float cinematicActivityStart { get; private set; }
|
||||
|
||||
private State state
|
||||
{
|
||||
get => _state;
|
||||
set
|
||||
{
|
||||
timeStateChanged = Time.time;
|
||||
_state = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool animState
|
||||
{
|
||||
get => _animState;
|
||||
private set
|
||||
{
|
||||
if (value == _animState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Debug.Log($"setting cinematic controller {gameObject.name} to: {value}");
|
||||
}
|
||||
|
||||
_animState = value;
|
||||
if (animParam.Length > 0)
|
||||
{
|
||||
SafeAnimator.SetBool(animator, animParam, value);
|
||||
}
|
||||
|
||||
if (receiversAnimParam.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < animParamReceivers.Length; i++)
|
||||
{
|
||||
animParamReceivers[i].GetComponent<IAnimParamReceiver>()?.ForwardAnimationParameterBool(receiversAnimParam, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (playerViewAnimationName.Length > 0 && player != null)
|
||||
{
|
||||
Animator componentInChildren = player.Body.GetComponentInChildren<Animator>();
|
||||
if (componentInChildren != null && componentInChildren.gameObject.activeInHierarchy)
|
||||
{
|
||||
SafeAnimator.SetBool(componentInChildren, playerViewAnimationName, value);
|
||||
}
|
||||
}
|
||||
|
||||
SetVrActiveParam();
|
||||
}
|
||||
}
|
||||
|
||||
public int managedUpdateIndex { get; set; }
|
||||
|
||||
public int managedLateUpdateIndex { get; set; }
|
||||
|
||||
public string GetProfileTag()
|
||||
{
|
||||
return nameof(RemotePlayerCinematicController);
|
||||
}
|
||||
|
||||
public void SetPlayer(RemotePlayer setplayer)
|
||||
{
|
||||
if (subscribed && player != setplayer)
|
||||
{
|
||||
Subscribe(player, false);
|
||||
Subscribe(setplayer, true);
|
||||
}
|
||||
|
||||
player = setplayer;
|
||||
}
|
||||
|
||||
public RemotePlayer GetPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
private void AddToUpdateManager()
|
||||
{
|
||||
BehaviourUpdateUtils.Register((IManagedUpdateBehaviour)this);
|
||||
BehaviourUpdateUtils.Register((IManagedLateUpdateBehaviour)this);
|
||||
}
|
||||
|
||||
private void RemoveFromUpdateManager()
|
||||
{
|
||||
BehaviourUpdateUtils.Deregister((IManagedUpdateBehaviour)this);
|
||||
BehaviourUpdateUtils.Deregister((IManagedLateUpdateBehaviour)this);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
AddToUpdateManager();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
RemoveFromUpdateManager();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
SetVrActiveParam();
|
||||
}
|
||||
|
||||
private void SetVrActiveParam()
|
||||
{
|
||||
string paramaterName = "vr_active";
|
||||
bool vrAnimationMode = GameOptions.GetVrAnimationMode();
|
||||
if (animator != null)
|
||||
{
|
||||
animator.SetBool(paramaterName, vrAnimationMode);
|
||||
}
|
||||
|
||||
foreach (GameObject animatedObject in animParamReceivers)
|
||||
{
|
||||
animatedObject.GetComponent<IAnimParamReceiver>()?.ForwardAnimationParameterBool(paramaterName, vrAnimationMode);
|
||||
}
|
||||
}
|
||||
|
||||
private bool UseEndTransform()
|
||||
{
|
||||
if (endTransform == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (onlyUseEndTransformInVr)
|
||||
{
|
||||
return GameOptions.GetVrAnimationMode();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SkipCinematic(RemotePlayer player)
|
||||
{
|
||||
this.player = player;
|
||||
if (player != null)
|
||||
{
|
||||
Transform component = player.Body.GetComponent<Transform>();
|
||||
if (UseEndTransform())
|
||||
{
|
||||
component.position = endTransform.position;
|
||||
component.rotation = endTransform.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
if (informGameObject != null)
|
||||
{
|
||||
informGameObject.SendMessage(nameof(CinematicModeTriggerBase.OnPlayerCinematicModeEnd), this, SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCinematicMode(RemotePlayer setplayer)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Debug.Log($"{gameObject.name}.StartCinematicMode");
|
||||
}
|
||||
|
||||
if (!cinematicModeActive)
|
||||
{
|
||||
player = null;
|
||||
if (!playInVr && GameOptions.GetVrAnimationMode())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Debug.Log($"{gameObject.name} skip cinematic");
|
||||
}
|
||||
|
||||
SkipCinematic(setplayer);
|
||||
return;
|
||||
}
|
||||
|
||||
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||||
cinematicModeActive = true;
|
||||
if (setplayer != null)
|
||||
{
|
||||
SetPlayer(setplayer);
|
||||
Subscribe(player, true);
|
||||
}
|
||||
|
||||
state = State.In;
|
||||
if (informGameObject != null)
|
||||
{
|
||||
informGameObject.SendMessage(nameof(DockedVehicleHandTarget.OnPlayerCinematicModeStart), this, SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
Transform component = player.Body.GetComponent<Transform>();
|
||||
playerFromPosition = component.position;
|
||||
playerFromRotation = component.rotation;
|
||||
if (playerViewInterpolateAnimParam.Length > 0)
|
||||
{
|
||||
SafeAnimator.SetBool(player.Body.GetComponentInChildren<Animator>(), playerViewInterpolateAnimParam, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interpolateAnimParam.Length > 0)
|
||||
{
|
||||
SafeAnimator.SetBool(animator, interpolateAnimParam, true);
|
||||
}
|
||||
|
||||
if (interpolateDuringAnimation)
|
||||
{
|
||||
animState = true;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Debug.Log($"{gameObject.name} successfully started cinematic");
|
||||
}
|
||||
|
||||
if (cinematicModeCount == 0)
|
||||
{
|
||||
cinematicActivityStart = Time.time;
|
||||
}
|
||||
|
||||
cinematicModeCount++;
|
||||
}
|
||||
else if (debug)
|
||||
{
|
||||
Debug.Log($"{gameObject.name} cinematic already active!");
|
||||
}
|
||||
}
|
||||
|
||||
public void EndCinematicMode(bool reset = false)
|
||||
{
|
||||
if (cinematicModeActive)
|
||||
{
|
||||
if (reset) // Added by us
|
||||
{
|
||||
animator.Rebind();
|
||||
animator.Update(0f);
|
||||
}
|
||||
|
||||
animator.cullingMode = AnimatorCullingMode.CullCompletely;
|
||||
animState = false;
|
||||
state = State.None;
|
||||
cinematicModeActive = false;
|
||||
cinematicModeCount--;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPlayerCinematicModeEnd()
|
||||
{
|
||||
if (!cinematicModeActive || onCinematicModeEndCall)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
UpdatePlayerPosition();
|
||||
}
|
||||
|
||||
animState = false;
|
||||
if (UseEndTransform())
|
||||
{
|
||||
state = State.Out;
|
||||
if (player != null)
|
||||
{
|
||||
Transform component = player.Body.GetComponent<Transform>();
|
||||
playerFromPosition = component.position;
|
||||
playerFromRotation = component.rotation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EndCinematicMode();
|
||||
}
|
||||
|
||||
if (informGameObject != null)
|
||||
{
|
||||
onCinematicModeEndCall = true;
|
||||
informGameObject.SendMessage(nameof(DockedVehicleHandTarget.OnPlayerCinematicModeEnd), this, SendMessageOptions.DontRequireReceiver);
|
||||
onCinematicModeEndCall = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePlayerPosition()
|
||||
{
|
||||
Transform component = player.Body.GetComponent<Transform>();
|
||||
component.position = animatedTransform.position;
|
||||
component.rotation = animatedTransform.rotation;
|
||||
}
|
||||
|
||||
public void ManagedLateUpdate()
|
||||
{
|
||||
if (!cinematicModeActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float num = Time.time - timeStateChanged;
|
||||
float timedOutScalar;
|
||||
Transform transform = null;
|
||||
if (player != null && player.Body)
|
||||
{
|
||||
transform = player.Body.GetComponent<Transform>();
|
||||
}
|
||||
|
||||
bool isVrAnimationMode = !GameOptions.GetVrAnimationMode();
|
||||
switch (state)
|
||||
{
|
||||
case State.In:
|
||||
timedOutScalar = interpolationTime != 0f && isVrAnimationMode ? Mathf.Clamp01(num / interpolationTime) : 1f;
|
||||
if (player != null && transform)
|
||||
{
|
||||
transform.position = Vector3.Lerp(playerFromPosition, animatedTransform.position, timedOutScalar);
|
||||
transform.rotation = Quaternion.Slerp(playerFromRotation, animatedTransform.rotation, timedOutScalar);
|
||||
}
|
||||
|
||||
if (timedOutScalar == 1f)
|
||||
{
|
||||
state = State.Update;
|
||||
animState = true;
|
||||
if (interpolateAnimParam.Length > 0)
|
||||
{
|
||||
SafeAnimator.SetBool(animator, interpolateAnimParam, false);
|
||||
}
|
||||
|
||||
if (playerViewInterpolateAnimParam.Length > 0 && player != null)
|
||||
{
|
||||
SafeAnimator.SetBool(player.Body.GetComponentInChildren<Animator>(), playerViewInterpolateAnimParam, false);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case State.Update:
|
||||
if (player != null)
|
||||
{
|
||||
UpdatePlayerPosition();
|
||||
}
|
||||
|
||||
break;
|
||||
case State.Out:
|
||||
timedOutScalar = interpolationTimeOut != 0f && isVrAnimationMode ? Mathf.Clamp01(num / interpolationTimeOut) : 1f;
|
||||
if (player != null && transform)
|
||||
{
|
||||
transform.position = Vector3.Lerp(playerFromPosition, endTransform.position, timedOutScalar);
|
||||
transform.rotation = Quaternion.Slerp(playerFromRotation, endTransform.rotation, timedOutScalar);
|
||||
}
|
||||
|
||||
if (timedOutScalar == 1f)
|
||||
{
|
||||
EndCinematicMode();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCinematicModeActive()
|
||||
{
|
||||
return cinematicModeActive;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
RemoveFromUpdateManager();
|
||||
if (subscribed)
|
||||
{
|
||||
Subscribe(player, false);
|
||||
}
|
||||
|
||||
EndCinematicMode();
|
||||
}
|
||||
|
||||
private void OnPlayerDeath(RemotePlayer player)
|
||||
{
|
||||
EndCinematicMode();
|
||||
animator.Rebind();
|
||||
}
|
||||
|
||||
private void Subscribe(RemotePlayer player, bool state)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
subscribed = false;
|
||||
}
|
||||
else if (subscribed != state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
player.PlayerDeathEvent.AddHandler(gameObject, OnPlayerDeath);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.PlayerDeathEvent.RemoveHandler(gameObject, OnPlayerDeath);
|
||||
}
|
||||
|
||||
subscribed = state;
|
||||
}
|
||||
}
|
||||
|
||||
public void ManagedUpdate()
|
||||
{
|
||||
if (!cinematicModeActive && subscribed)
|
||||
{
|
||||
Subscribe(player, false);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user