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