Files
AppleHillsProduction/Assets/Scripts/PlayerTouchController.cs

147 lines
4.4 KiB
C#

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<Rigidbody>();
rb2d = GetComponent<Rigidbody2D>();
aiPath = GetComponent<AIPath>(); // Get AIPath component
// Find art prefab and animator
artTransform = transform.Find("CharacterArt");
if (artTransform != null)
{
animator = artTransform.GetComponent<Animator>();
}
else
{
animator = GetComponentInChildren<Animator>(); // 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();
}
}
}