using NightclubArcadia.Interaction;
using NightclubArcadia.UI;
using StarterAssets;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace NightclubArcadia.Player
{
public enum MotionSource
{
None,
Direct,
Navigation
}
///
/// Sole writer of StarterAssetsInputs move/sprint. Picks one input source
/// per frame: direct keyboard/gamepad or click-to-move navigation.
///
[DefaultExecutionOrder(-50)]
public sealed class PlayerMotionArbiter : MonoBehaviour
{
[SerializeField] float directInputCancelThreshold = 0.15f;
[SerializeField] float runDistanceThreshold = 6f;
StarterAssetsInputs playerInputs;
PlayerControlLock controlLock;
ClickToMoveController clickToMove;
#if ENABLE_INPUT_SYSTEM
PlayerInput playerInput;
#endif
public MotionSource ActiveSource { get; private set; }
void Awake()
{
playerInputs = GetComponent();
controlLock = GetComponent();
clickToMove = GetComponent();
#if ENABLE_INPUT_SYSTEM
playerInput = GetComponent();
#endif
}
public void ResetState()
{
ActiveSource = MotionSource.None;
clickToMove?.Cancel();
WriteInput(Vector2.zero, false);
}
void Update()
{
if (controlLock != null && controlLock.IsLocked)
{
clickToMove?.Cancel();
ActiveSource = MotionSource.None;
WriteInput(Vector2.zero, false);
return;
}
#if ENABLE_INPUT_SYSTEM
var raw = playerInput.actions["Move"].ReadValue();
#else
var raw = Vector2.zero;
#endif
if (raw.sqrMagnitude > directInputCancelThreshold * directInputCancelThreshold)
{
clickToMove?.Cancel();
ActiveSource = MotionSource.Direct;
WriteInput(raw, ReadDirectSprint());
return;
}
if (clickToMove != null && clickToMove.HasPath)
{
ActiveSource = MotionSource.Navigation;
WriteInput(clickToMove.DesiredMoveInput, ShouldNavigationSprint());
return;
}
ActiveSource = MotionSource.None;
WriteInput(Vector2.zero, false);
}
bool ReadDirectSprint()
{
#if ENABLE_INPUT_SYSTEM
return playerInput.actions["Sprint"].IsPressed();
#else
return false;
#endif
}
bool ShouldNavigationSprint()
{
return clickToMove != null && clickToMove.WantsSprint;
}
void WriteInput(Vector2 move, bool sprint)
{
if (playerInputs == null)
{
return;
}
playerInputs.MoveInput(move);
playerInputs.SprintInput(sprint);
}
}
}