using System.Threading.Tasks;
using Core;
using Input;
using UnityEngine;
namespace Utils
{
///
/// Utility methods for character movement operations.
/// Extracted from interaction/controller code for reusability.
///
public static class MovementUtilities
{
///
/// Moves a character to a target position and waits for arrival.
/// Works with any controller implementing IInteractingCharacter.
///
/// The character to move (must implement IInteractingCharacter)
/// World position to move to
/// Task that completes when the character arrives or movement is cancelled
public static async Task MoveToPositionAsync(IInteractingCharacter character, Vector3 targetPosition)
{
if (character == null)
{
Logging.Warning("[MovementUtilities] Cannot move null character");
return false;
}
var tcs = new TaskCompletionSource();
void OnArrivedLocal()
{
character.OnArrivedAtTarget -= OnArrivedLocal;
character.OnMoveToCancelled -= OnCancelledLocal;
tcs.TrySetResult(true);
}
void OnCancelledLocal()
{
character.OnArrivedAtTarget -= OnArrivedLocal;
character.OnMoveToCancelled -= OnCancelledLocal;
tcs.TrySetResult(false);
}
character.OnArrivedAtTarget += OnArrivedLocal;
character.OnMoveToCancelled += OnCancelledLocal;
character.MoveToAndNotify(targetPosition);
return await tcs.Task;
}
///
/// Calculates a stop position at a given distance from a target position towards a character.
///
/// The target position
/// The character's current position
/// Distance from target to stop at
/// The calculated stop position
public static Vector3 CalculateStopPosition(Vector3 targetPosition, Vector3 characterPosition, float stopDistance)
{
Vector3 toCharacter = (characterPosition - targetPosition).normalized;
return targetPosition + toCharacter * stopDistance;
}
}
}