A bit wonky but working switching

This commit is contained in:
Michal Pikulski
2025-12-15 00:57:50 +01:00
parent 8995dd1949
commit b14fdfbe68
12 changed files with 282 additions and 153 deletions

View File

@@ -9,9 +9,10 @@ namespace Input
/// <summary>
/// Base class for player movement controllers.
/// Handles tap-to-move and hold-to-move input with pathfinding or direct movement.
/// Implements IInteractingCharacter to enable interaction with items.
/// Derived classes can override to add specialized behavior (e.g., shader updates).
/// </summary>
public abstract class BasePlayerMovementController : ManagedBehaviour, ITouchInputConsumer
public abstract class BasePlayerMovementController : ManagedBehaviour, ITouchInputConsumer, IInteractingCharacter
{
[Header("Movement")]
[SerializeField] protected float moveSpeed = 5f;
@@ -42,6 +43,12 @@ namespace Input
public event System.Action OnMovementStarted;
public event System.Action OnMovementStopped;
// IInteractingCharacter implementation - scripted movement for interactions
private Coroutine _moveToCoroutine;
private bool _interruptMoveTo;
public event System.Action OnArrivedAtTarget;
public event System.Action OnMoveToCancelled;
// Components
protected AIPath _aiPath;
protected Animator _animator;
@@ -95,6 +102,7 @@ namespace Input
public virtual void OnTap(Vector2 worldPosition)
{
InterruptMoveTo(); // Cancel any scripted movement
Logging.Debug($"[{GetType().Name}] OnTap at {worldPosition}");
if (_aiPath != null)
{
@@ -109,6 +117,7 @@ namespace Input
public virtual void OnHoldStart(Vector2 worldPosition)
{
InterruptMoveTo(); // Cancel any scripted movement
Logging.Debug($"[{GetType().Name}] OnHoldStart at {worldPosition}");
_lastHoldPosition = worldPosition;
_isHolding = true;
@@ -318,6 +327,78 @@ namespace Input
}
#endregion
#region IInteractingCharacter Implementation
/// <summary>
/// Moves the character to a specific target position and notifies via events when arrived or cancelled.
/// This is used by systems like interactions to orchestrate scripted movement.
/// </summary>
public virtual void MoveToAndNotify(Vector3 target)
{
// Cancel any previous move-to coroutine
if (_moveToCoroutine != null)
{
StopCoroutine(_moveToCoroutine);
}
_interruptMoveTo = false;
// Ensure pathfinding is enabled for MoveToAndNotify
if (_aiPath != null)
{
_aiPath.enabled = true;
_aiPath.canMove = true;
_aiPath.isStopped = false;
}
_moveToCoroutine = StartCoroutine(MoveToTargetCoroutine(target));
}
/// <summary>
/// Cancels any in-progress MoveToAndNotify operation and fires the cancellation event.
/// </summary>
public virtual void InterruptMoveTo()
{
_interruptMoveTo = true;
_isHolding = false;
_directMoveVelocity = Vector3.zero;
if (Settings != null && Settings.DefaultHoldMovementMode == HoldMovementMode.Direct && _aiPath != null)
_aiPath.enabled = false;
OnMoveToCancelled?.Invoke();
}
/// <summary>
/// Coroutine for moving the character to a target position and firing arrival/cancel events.
/// </summary>
protected virtual System.Collections.IEnumerator MoveToTargetCoroutine(Vector3 target)
{
if (_aiPath != null)
{
_aiPath.destination = target;
_aiPath.maxSpeed = Settings.MoveSpeed;
_aiPath.maxAcceleration = Settings.MaxAcceleration;
}
while (!_interruptMoveTo)
{
Vector2 current2D = new Vector2(transform.position.x, transform.position.y);
Vector2 target2D = new Vector2(target.x, target.y);
float dist = Vector2.Distance(current2D, target2D);
if (dist <= Settings.StopDistance + 0.2f)
{
break;
}
yield return null;
}
_moveToCoroutine = null;
if (!_interruptMoveTo)
{
OnArrivedAtTarget?.Invoke();
}
}
#endregion
}
}