151 lines
3.9 KiB
C#
151 lines
3.9 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Vanguard.Battle;
|
|
using Vanguard.Board3D;
|
|
|
|
namespace Vanguard.Board3D
|
|
{
|
|
/// <summary>
|
|
/// Единый планировщик карточных перемещений. Карточки анимируются
|
|
/// Card3D, аниматор отвечает за stagger, очередь и InputLock.
|
|
/// </summary>
|
|
public sealed class CardMoveAnimator
|
|
{
|
|
private sealed class Request
|
|
{
|
|
public Card3D Card;
|
|
public Vector3 FromPosition;
|
|
public Quaternion FromRotation;
|
|
public Vector3 FromScale;
|
|
public float Duration;
|
|
public float ArcHeight;
|
|
}
|
|
|
|
private readonly Queue<Request> _queue = new Queue<Request>();
|
|
private readonly List<Card3D> _active = new List<Card3D>();
|
|
private readonly InputLockService _inputLock;
|
|
private AnimationConfig _config;
|
|
private float _delay;
|
|
private bool _locked;
|
|
|
|
public CardMoveAnimator(
|
|
InputLockService inputLock,
|
|
AnimationConfig config)
|
|
{
|
|
_inputLock = inputLock;
|
|
_config = config;
|
|
}
|
|
|
|
public bool IsBusy => _queue.Count > 0 || _active.Count > 0;
|
|
|
|
public void SetConfig(AnimationConfig config)
|
|
{
|
|
_config = config;
|
|
}
|
|
|
|
public void Enqueue(
|
|
Card3D card,
|
|
Vector3 fromPosition,
|
|
Quaternion fromRotation,
|
|
Vector3 fromScale,
|
|
float duration,
|
|
float arcHeight)
|
|
{
|
|
if (card == null || card.IsDragging)
|
|
return;
|
|
|
|
EnsureLock();
|
|
_queue.Enqueue(new Request
|
|
{
|
|
Card = card,
|
|
FromPosition = fromPosition,
|
|
FromRotation = fromRotation,
|
|
FromScale = fromScale,
|
|
Duration = duration,
|
|
ArcHeight = arcHeight,
|
|
});
|
|
}
|
|
|
|
public void Tick(float deltaTime)
|
|
{
|
|
if (_active.Count > 0)
|
|
{
|
|
for (var i = _active.Count - 1; i >= 0; i--)
|
|
{
|
|
if (_active[i] == null || !_active[i].IsMoving)
|
|
_active.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
if (_queue.Count > 0)
|
|
{
|
|
_delay -= Mathf.Max(0f, deltaTime);
|
|
if (_delay <= 0f)
|
|
StartNext();
|
|
}
|
|
|
|
if (!IsBusy)
|
|
ReleaseLock();
|
|
}
|
|
|
|
public void CancelAll(bool snapCards = false)
|
|
{
|
|
_queue.Clear();
|
|
foreach (var card in _active)
|
|
{
|
|
if (card != null)
|
|
card.StopMove(snapCards);
|
|
}
|
|
|
|
_active.Clear();
|
|
_delay = 0f;
|
|
ReleaseLock();
|
|
}
|
|
|
|
private void StartNext()
|
|
{
|
|
if (_queue.Count == 0)
|
|
return;
|
|
|
|
var request = _queue.Dequeue();
|
|
var card = request.Card;
|
|
if (card == null || card.IsDragging)
|
|
{
|
|
_delay = 0f;
|
|
return;
|
|
}
|
|
|
|
card.StartArcMove(
|
|
request.FromPosition,
|
|
request.FromRotation,
|
|
request.FromScale,
|
|
request.Duration,
|
|
request.ArcHeight);
|
|
|
|
if (card.IsMoving)
|
|
_active.Add(card);
|
|
_delay = Mathf.Max(0.01f, _config != null
|
|
? _config.moveDelayBetweenCards
|
|
: 0.18f);
|
|
}
|
|
|
|
private void EnsureLock()
|
|
{
|
|
if (_locked)
|
|
return;
|
|
|
|
_inputLock?.Acquire("card-move");
|
|
_locked = true;
|
|
}
|
|
|
|
private void ReleaseLock()
|
|
{
|
|
if (!_locked)
|
|
return;
|
|
|
|
_inputLock?.Release("card-move");
|
|
_locked = false;
|
|
}
|
|
}
|
|
}
|