91 lines
2.6 KiB
C#
91 lines
2.6 KiB
C#
using System;
|
|
using Northbound.Core;
|
|
using UnityEngine;
|
|
|
|
namespace Northbound.Gameplay.Player
|
|
{
|
|
public sealed class PlayerActionController : MonoBehaviour
|
|
{
|
|
[SerializeField] private KeyCode cancelKey = KeyCode.Escape;
|
|
|
|
private PlayerActionDefinition currentAction;
|
|
private float actionEndsAt;
|
|
private bool hasActiveAction;
|
|
private Action completion;
|
|
private Action<float> cancellation;
|
|
|
|
public bool IsActing => hasActiveAction;
|
|
public bool CanStartAction => !IsActing;
|
|
public bool CanMove => !IsActing || currentAction.AllowsMovement;
|
|
public string CurrentActionName => IsActing ? currentAction.ActionName : string.Empty;
|
|
public bool CurrentActionCanBeCancelled => IsActing && currentAction.CanBeCancelled;
|
|
public float RemainingTime => IsActing ? Mathf.Max(0f, actionEndsAt - Time.time) : 0f;
|
|
|
|
private void Update()
|
|
{
|
|
if (!IsActing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (currentAction.CanBeCancelled && Input.GetKeyDown(cancelKey))
|
|
{
|
|
TryCancelCurrentAction();
|
|
return;
|
|
}
|
|
|
|
if (Time.time >= actionEndsAt)
|
|
{
|
|
CompleteCurrentAction();
|
|
}
|
|
}
|
|
|
|
public bool TryBeginAction(PlayerActionDefinition action, Action onCompleted = null, Action<float> onCancelled = null)
|
|
{
|
|
if (!CanStartAction)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
currentAction = action;
|
|
actionEndsAt = Time.time + action.Duration;
|
|
completion = onCompleted;
|
|
cancellation = onCancelled;
|
|
hasActiveAction = true;
|
|
return true;
|
|
}
|
|
|
|
public bool TryCancelCurrentAction()
|
|
{
|
|
if (!CurrentActionCanBeCancelled)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var callback = cancellation;
|
|
var progress = currentAction.Duration <= 0f
|
|
? 1f
|
|
: Mathf.Clamp01(1f - RemainingTime / currentAction.Duration);
|
|
ClearCurrentAction();
|
|
callback?.Invoke(progress);
|
|
return true;
|
|
}
|
|
|
|
private void CompleteCurrentAction()
|
|
{
|
|
var callback = completion;
|
|
ClearCurrentAction();
|
|
callback?.Invoke();
|
|
}
|
|
|
|
private void ClearCurrentAction()
|
|
{
|
|
hasActiveAction = false;
|
|
actionEndsAt = 0f;
|
|
currentAction = default;
|
|
completion = null;
|
|
cancellation = null;
|
|
}
|
|
}
|
|
}
|