Files
BH3/Assets/Scripts/Assembly-CSharp/MoleMole/FollowTimedPullZ.cs
2025-08-13 09:26:42 +08:00

165 lines
4.4 KiB
C#

using FullInspector;
using UnityEngine;
namespace MoleMole
{
public class FollowTimedPullZ : BaseFollowShortState
{
private enum State
{
Entering = 0,
PullZ = 1,
Exiting = 2
}
[ShowInInspector]
private float _origRadius;
[ShowInInspector]
private float _targetRadius;
[ShowInInspector]
private float _origElevation;
[ShowInInspector]
private float _targetElevation;
[ShowInInspector]
private float _origCenterY;
[ShowInInspector]
private float _targetCenterY;
[ShowInInspector]
private float _origFOV;
[ShowInInspector]
private float _targetFOV;
[ShowInInspector]
private float _pullZTimer;
[ShowInInspector]
private float _timer;
[ShowInInspector]
private float _exitDuration;
[ShowInInspector]
private float _lerpTimer;
[ShowInInspector]
private float _lerpTotalTime;
[ShowInInspector]
private string _lerpCurveName;
[ShowInInspector]
private AnimationCurve _lerpCurve;
[ShowInInspector]
private State _state;
public FollowTimedPullZ(MainCameraFollowState followState)
: base(followState)
{
base.isSkippingBaseState = false;
}
public void SetTimedPullZ(float radiusRatio, float elevationAngles, float centerYOffset, float fovOffset, float time, float lerpTime, string lerpCurveName)
{
_targetRadius = radiusRatio * _owner.recoverState.GetOriginalRadius();
_targetElevation = _owner.recoverState.GetOriginalElevation() + elevationAngles;
_targetCenterY = _owner.recoverState.GetOriginalCenterY() + centerYOffset;
_targetFOV = Mathf.Max(0f, _owner.recoverState.GetOriginalFOV() + fovOffset);
_pullZTimer = time;
_lerpTimer = lerpTime;
_lerpTotalTime = lerpTime;
_lerpCurveName = lerpCurveName;
_lerpCurve = CameraData.GetCameraCurveByName(_lerpCurveName);
}
public override void Enter()
{
if (_owner.recoverState.active)
{
_owner.recoverState.CancelAndStopAtCurrentState();
}
_origRadius = _owner.recoverState.GetOriginalRadius();
_origElevation = _owner.recoverState.GetOriginalElevation();
_origCenterY = _owner.recoverState.GetOriginalCenterY();
_origFOV = _owner.mainCamera.cameraComponent.fieldOfView;
_timer = 0f;
_state = State.Entering;
}
public override void Update()
{
if (_state == State.Entering)
{
_lerpTimer -= Time.deltaTime * _owner.mainCamera.TimeScale;
if (_lerpTimer > 0f)
{
float t = ((_lerpCurve != null) ? _lerpCurve.Evaluate(1f - _lerpTimer / _lerpTotalTime) : (1f - _lerpTimer / _lerpTotalTime));
_owner.anchorRadius = Mathf.Clamp(Mathf.Lerp(_origRadius, _targetRadius, t), 4f, 11f);
_owner.anchorElevation = Mathf.Lerp(_origElevation, _targetElevation, t);
_owner.followCenterY = Mathf.Lerp(_origCenterY, _targetCenterY, t);
_owner.cameraFOV = Mathf.Lerp(_origFOV, _targetFOV, t);
}
else
{
_owner.anchorRadius = Mathf.Clamp(_targetRadius, 4f, 11f);
_owner.anchorElevation = _targetElevation;
_owner.followCenterY = _targetCenterY;
_owner.cameraFOV = _targetFOV;
_state = State.PullZ;
}
}
else if (_state == State.PullZ)
{
_pullZTimer -= Time.deltaTime * _owner.mainCamera.TimeScale;
if (_pullZTimer <= 0f)
{
float a = 0.1f * Mathf.Abs(_targetFOV - _origFOV);
float b = 0.35f * Mathf.Abs(_targetRadius - _origRadius);
_exitDuration = Mathf.Max(a, b);
_state = State.Exiting;
}
}
else if (_state == State.Exiting)
{
_timer += Time.deltaTime * _owner.mainCamera.TimeScale;
if (_timer < _exitDuration)
{
_owner.anchorRadius = Mathf.Clamp(Mathf.Lerp(_targetRadius, _origRadius, _timer / _exitDuration), 4f, 11f);
_owner.anchorElevation = Mathf.Lerp(_targetElevation, _origElevation, _timer / _exitDuration);
_owner.followCenterY = Mathf.Lerp(_targetCenterY, _origCenterY, _timer / _exitDuration);
_owner.cameraFOV = Mathf.Lerp(_targetFOV, _origFOV, _timer / _exitDuration);
}
else
{
_owner.anchorRadius = Mathf.Clamp(_origRadius, 4f, 11f);
_owner.anchorElevation = _origElevation;
_owner.followCenterY = _origCenterY;
_owner.cameraFOV = _origFOV;
End();
}
}
}
public void ForceToExitState()
{
_pullZTimer = 0f;
float a = 0.1f * Mathf.Abs(_targetFOV - _origFOV);
float b = 0.35f * Mathf.Abs(_targetRadius - _origRadius);
_exitDuration = Mathf.Max(a, b);
_state = State.Exiting;
}
public override void Exit()
{
_owner.recoverState.TryRecover();
}
}
}