Files
Northbound/Assets/Northbound/Gameplay/Player/PlayerActionController.cs
T

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;
}
}
}