147 lines
4.4 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|