VanguardReMaster/client/Assets/Vanguard/Runtime/Battle/TriggerCheckSequence.cs

154 lines
4.0 KiB
C#

using UnityEngine;
using Vanguard.Battle;
namespace Vanguard.Battle
{
/// <summary>
/// Оркестратор кинематографичной проверки триггера:
/// zoom → reveal hold → return; повторный zoom в цепочке.
/// </summary>
public sealed class TriggerCheckSequence
{
private enum Stage
{
Idle,
Zooming,
Holding,
Returning,
}
private readonly CameraDirector _camera;
private readonly InputLockService _inputLock;
private Stage _stage;
private float _deadline;
private bool _chainActive;
private bool _restoreRequested;
private bool _lockHeld;
public TriggerCheckSequence(
CameraDirector camera,
InputLockService inputLock)
{
_camera = camera;
_inputLock = inputLock;
}
public bool IsBusy => _stage != Stage.Idle;
public void ShowTrigger(
AnimationConfig config,
Vector3 worldPoint)
{
if (_camera == null)
return;
if (!_chainActive)
{
_camera.BeginChain();
_chainActive = true;
}
Acquire();
_restoreRequested = false;
var zoom = config != null
? config.cameraZoomDuration
: 0.35f;
var hold = config != null
? config.triggerRevealHold
: 1.2f;
_camera.ZoomTo(worldPoint, zoom);
_stage = Stage.Zooming;
_deadline = Time.unscaledTime + zoom + hold;
}
public void ReturnForChoice(AnimationConfig config)
{
if (!_chainActive)
return;
var duration = config != null
? config.cameraReturnDuration
: 0.4f;
_camera.ReturnToOrigin(duration);
_stage = Stage.Returning;
_deadline = Time.unscaledTime + duration;
}
public void EndChain(AnimationConfig config)
{
if (!_chainActive)
{
Release();
return;
}
var duration = config != null
? config.cameraReturnDuration
: 0.4f;
_restoreRequested = true;
_camera.ReturnToOrigin(duration);
_stage = Stage.Returning;
_deadline = Time.unscaledTime + duration;
}
public void Tick(AnimationConfig config)
{
if (_stage == Stage.Idle)
return;
if (_stage == Stage.Zooming
&& Time.unscaledTime >= _deadline)
{
var duration = config != null
? config.cameraReturnDuration
: 0.4f;
_camera.ReturnToOrigin(duration);
_stage = Stage.Returning;
_deadline = Time.unscaledTime + duration;
return;
}
if (_stage == Stage.Returning
&& Time.unscaledTime >= _deadline)
{
_stage = Stage.Idle;
Release();
if (_restoreRequested)
{
_restoreRequested = false;
_chainActive = false;
_camera.Restore();
}
}
}
private void Acquire()
{
if (_lockHeld)
return;
_inputLock?.Acquire("trigger-sequence");
_lockHeld = true;
}
private void Release()
{
if (!_lockHeld)
return;
_inputLock?.Release("trigger-sequence");
_lockHeld = false;
}
public void Cancel()
{
_stage = Stage.Idle;
_chainActive = false;
Release();
_camera?.Restore();
}
}
}