using UnityEngine; #if ENABLE_INPUT_SYSTEM using UnityEngine.InputSystem; #endif using Pathfinding; // Add this at the top // Basic touch/mouse movement controller suitable for top-down 2D or 3D overworld // Attach to the player GameObject. Works with or without Rigidbody/Rigidbody2D. public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer { Vector3 targetPosition; bool hasTarget = false; Rigidbody rb3d; Rigidbody2D rb2d; AIPath aiPath; // Reference to AIPath private Animator animator; private Transform artTransform; public delegate void ArrivedAtTargetHandler(); public event ArrivedAtTargetHandler OnArrivedAtTarget; public event System.Action OnMoveToCancelled; private Coroutine moveToCoroutine; private bool interruptMoveTo = false; void Awake() { rb3d = GetComponent(); rb2d = GetComponent(); aiPath = GetComponent(); // Get AIPath component // Find art prefab and animator artTransform = transform.Find("CharacterArt"); if (artTransform != null) { animator = artTransform.GetComponent(); } else { animator = GetComponentInChildren(); // fallback } } void Start() { // Initialize target to current position so object doesn't snap targetPosition = transform.position; hasTarget = false; // Register as default consumer in Start, after InputManager is likely initialized InputManager.Instance?.SetDefaultConsumer(this); } void OnEnable() { // No longer register here } // Remove Update and HandleInput public void OnTouchPress(Vector2 worldPosition) { // If moving to pickup, interrupt InterruptMoveTo(); Debug.Log($"PlayerTouchController.OnTouchPress received worldPosition: {worldPosition}"); SetTargetPosition(worldPosition); } public void OnTouchPosition(Vector2 screenPosition) { Debug.Log($"PlayerTouchController.OnTouchPosition called with screenPosition: {screenPosition}"); // Optionally handle drag/move here } void SetTargetPosition(Vector2 worldPosition) { Debug.Log($"PlayerTouchController.SetTargetPosition: worldPosition={worldPosition}"); targetPosition = new Vector3(worldPosition.x, worldPosition.y, transform.position.z); hasTarget = true; if (aiPath != null) { aiPath.destination = targetPosition; aiPath.maxSpeed = GameManager.Instance.MoveSpeed; Debug.Log($"AIPath destination set to {targetPosition}"); } else { Debug.LogWarning("AIPath component not found, falling back to direct movement"); } } void Update() { // Update animator speed parameter if (animator != null && aiPath != null) { float normalizedSpeed = aiPath.velocity.magnitude / aiPath.maxSpeed; animator.SetFloat("Speed", Mathf.Clamp01(normalizedSpeed)); } } // Remove FixedUpdate and MoveTowardsTarget, as AIPath handles movement // Move to a target position, notify when arrived public void MoveToAndNotify(Vector3 target) { if (moveToCoroutine != null) { StopCoroutine(moveToCoroutine); } interruptMoveTo = false; moveToCoroutine = StartCoroutine(MoveToTargetCoroutine(target)); } public void InterruptMoveTo() { interruptMoveTo = true; OnMoveToCancelled?.Invoke(); } private System.Collections.IEnumerator MoveToTargetCoroutine(Vector3 target) { hasTarget = true; targetPosition = target; if (aiPath != null) { aiPath.destination = target; aiPath.maxSpeed = GameManager.Instance.MoveSpeed; } 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 <= GameManager.Instance.StopDistance + 0.2f) { break; } yield return null; } hasTarget = false; moveToCoroutine = null; if (!interruptMoveTo) { OnArrivedAtTarget?.Invoke(); } } }