Update touch input settings
This commit is contained in:
@@ -22,6 +22,7 @@ MonoBehaviour:
|
|||||||
moveSpeed: 20
|
moveSpeed: 20
|
||||||
stopDistance: 0.1
|
stopDistance: 0.1
|
||||||
useRigidbody: 1
|
useRigidbody: 1
|
||||||
|
defaultHoldMovementMode: 1
|
||||||
followUpdateInterval: 0.1
|
followUpdateInterval: 0.1
|
||||||
followerSpeedMultiplier: 1.2
|
followerSpeedMultiplier: 1.2
|
||||||
heldIconDisplayHeight: 2
|
heldIconDisplayHeight: 2
|
||||||
|
|||||||
@@ -23,6 +23,15 @@
|
|||||||
"processors": "",
|
"processors": "",
|
||||||
"interactions": "",
|
"interactions": "",
|
||||||
"initialStateCheck": false
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TouchDelta",
|
||||||
|
"type": "Value",
|
||||||
|
"id": "99ae0aa3-a70e-4afc-8a8a-c7d6144fa75b",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"bindings": [
|
"bindings": [
|
||||||
@@ -41,12 +50,23 @@
|
|||||||
"name": "",
|
"name": "",
|
||||||
"id": "f3dcd77f-15e5-4621-af67-001e6b08e3e6",
|
"id": "f3dcd77f-15e5-4621-af67-001e6b08e3e6",
|
||||||
"path": "<Touchscreen>/Press",
|
"path": "<Touchscreen>/Press",
|
||||||
"interactions": "Hold",
|
"interactions": "Press(behavior=2)",
|
||||||
"processors": "",
|
"processors": "",
|
||||||
"groups": "",
|
"groups": "",
|
||||||
"action": "TouchPress",
|
"action": "TouchPress",
|
||||||
"isComposite": false,
|
"isComposite": false,
|
||||||
"isPartOfComposite": false
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "19cc6a3f-9316-4da5-8e35-8297e02b8f6c",
|
||||||
|
"path": "<Touchscreen>/delta",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "TouchDelta",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,19 +20,48 @@ public class EndlessDescenderController : MonoBehaviour, ITouchInputConsumer
|
|||||||
isTouchActive = false;
|
isTouchActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTouchPress(Vector2 worldPosition)
|
// Implement new ITouchInputConsumer contract
|
||||||
|
public void OnTap(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Only update horizontal position
|
// Treat tap as a quick move to the tapped X position
|
||||||
targetFingerX = Mathf.Clamp(worldPosition.x, GameManager.Instance.EndlessDescenderClampXMin, GameManager.Instance.EndlessDescenderClampXMax);
|
targetFingerX = Mathf.Clamp(worldPosition.x, GameManager.Instance.EndlessDescenderClampXMin, GameManager.Instance.EndlessDescenderClampXMax);
|
||||||
isTouchActive = true;
|
isTouchActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTouchPosition(Vector2 worldPosition)
|
public void OnDragStart(Vector2 position)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDrag(Vector2 position)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDragEnd(Vector2 position)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnHoldStart(Vector2 worldPosition)
|
||||||
|
{
|
||||||
|
// Start hold, update target X
|
||||||
|
targetFingerX = Mathf.Clamp(worldPosition.x, GameManager.Instance.EndlessDescenderClampXMin, GameManager.Instance.EndlessDescenderClampXMax);
|
||||||
|
isTouchActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnHold(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Update target x as finger moves
|
// Update target x as finger moves
|
||||||
targetFingerX = Mathf.Clamp(worldPosition.x, GameManager.Instance.EndlessDescenderClampXMin, GameManager.Instance.EndlessDescenderClampXMax);
|
targetFingerX = Mathf.Clamp(worldPosition.x, GameManager.Instance.EndlessDescenderClampXMin, GameManager.Instance.EndlessDescenderClampXMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnHoldEnd(Vector2 worldPosition)
|
||||||
|
{
|
||||||
|
// Stop hold
|
||||||
|
isTouchActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
if (!isTouchActive) return;
|
if (!isTouchActive) return;
|
||||||
|
|||||||
@@ -74,4 +74,5 @@ public class GameManager : MonoBehaviour
|
|||||||
public float EndlessDescenderClampXMin => gameSettings != null ? gameSettings.endlessDescenderClampXMin : -5f;
|
public float EndlessDescenderClampXMin => gameSettings != null ? gameSettings.endlessDescenderClampXMin : -5f;
|
||||||
public float EndlessDescenderClampXMax => gameSettings != null ? gameSettings.endlessDescenderClampXMax : 5f;
|
public float EndlessDescenderClampXMax => gameSettings != null ? gameSettings.endlessDescenderClampXMax : 5f;
|
||||||
public float EndlessDescenderSpeedExponent => gameSettings != null ? gameSettings.endlessDescenderSpeedExponent : 2.5f;
|
public float EndlessDescenderSpeedExponent => gameSettings != null ? gameSettings.endlessDescenderSpeedExponent : 2.5f;
|
||||||
|
public GameSettings.HoldMovementMode DefaultHoldMovementMode => gameSettings != null ? gameSettings.defaultHoldMovementMode : GameSettings.HoldMovementMode.Pathfinding;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class GameSettings : ScriptableObject
|
|||||||
public float moveSpeed = 5f;
|
public float moveSpeed = 5f;
|
||||||
public float stopDistance = 0.1f;
|
public float stopDistance = 0.1f;
|
||||||
public bool useRigidbody = true;
|
public bool useRigidbody = true;
|
||||||
|
public enum HoldMovementMode { Pathfinding, Direct }
|
||||||
|
public HoldMovementMode defaultHoldMovementMode = HoldMovementMode.Pathfinding;
|
||||||
|
|
||||||
[Header("Backend Settings")]
|
[Header("Backend Settings")]
|
||||||
[Tooltip("Technical parameters, not for design tuning")]
|
[Tooltip("Technical parameters, not for design tuning")]
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
public interface ITouchInputConsumer
|
public interface ITouchInputConsumer
|
||||||
{
|
{
|
||||||
void OnTouchPress(Vector2 screenPosition);
|
void OnTap(Vector2 position);
|
||||||
void OnTouchPosition(Vector2 screenPosition);
|
void OnDragStart(Vector2 position);
|
||||||
|
void OnDrag(Vector2 position);
|
||||||
|
void OnDragEnd(Vector2 position);
|
||||||
|
void OnHoldStart(Vector2 position);
|
||||||
|
void OnHold(Vector2 position);
|
||||||
|
void OnHoldEnd(Vector2 position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,14 @@ public class InputManager : MonoBehaviour
|
|||||||
private bool isTouchHeld = false;
|
private bool isTouchHeld = false;
|
||||||
private bool lastFrameInteracted = false;
|
private bool lastFrameInteracted = false;
|
||||||
|
|
||||||
|
// Tap/drag detection state
|
||||||
|
private Vector2 pressStartPosition;
|
||||||
|
private float pressStartTime;
|
||||||
|
private bool isPressed = false;
|
||||||
|
private bool isDragging = false;
|
||||||
|
private float dragThreshold = 10f; // pixels
|
||||||
|
private float tapTimeThreshold = 0.2f; // seconds
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
_instance = this;
|
_instance = this;
|
||||||
@@ -76,46 +84,53 @@ public class InputManager : MonoBehaviour
|
|||||||
private void OnTouchPressStarted(InputAction.CallbackContext ctx)
|
private void OnTouchPressStarted(InputAction.CallbackContext ctx)
|
||||||
{
|
{
|
||||||
// Touch started (finger down)
|
// Touch started (finger down)
|
||||||
Vector3 _screenPos = Camera.main.ScreenToWorldPoint(touchPositionAction.ReadValue<Vector2>());
|
Vector2 screenPos = touchPositionAction.ReadValue<Vector2>();
|
||||||
Vector2 screenPos = new Vector2(_screenPos.x, _screenPos.y);
|
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
|
||||||
lastFrameInteracted = TryDelegateToInteractable(screenPos);
|
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
||||||
|
lastFrameInteracted = TryDelegateToInteractable(worldPos2D);
|
||||||
if (!lastFrameInteracted)
|
if (!lastFrameInteracted)
|
||||||
defaultConsumer?.OnTouchPress(screenPos);
|
{
|
||||||
isTouchHeld = true;
|
pressStartPosition = screenPos;
|
||||||
|
pressStartTime = Time.time;
|
||||||
|
isPressed = true;
|
||||||
|
isDragging = false;
|
||||||
|
defaultConsumer?.OnHoldStart(worldPos2D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTouchPressCanceled(InputAction.CallbackContext ctx)
|
private void OnTouchPressCanceled(InputAction.CallbackContext ctx)
|
||||||
{
|
{
|
||||||
// Touch released (finger up)
|
Vector2 screenPos = touchPositionAction.ReadValue<Vector2>();
|
||||||
isTouchHeld = false;
|
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
|
||||||
// Reset lastFrameInteracted for next frame
|
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
||||||
|
if (!lastFrameInteracted)
|
||||||
|
{
|
||||||
|
float timeHeld = Time.time - pressStartTime;
|
||||||
|
float dist = Vector2.Distance(screenPos, pressStartPosition);
|
||||||
|
if (!isDragging && timeHeld < tapTimeThreshold && dist < dragThreshold)
|
||||||
|
{
|
||||||
|
defaultConsumer?.OnTap(worldPos2D);
|
||||||
|
}
|
||||||
|
defaultConsumer?.OnHoldEnd(worldPos2D);
|
||||||
|
}
|
||||||
|
isPressed = false;
|
||||||
|
isDragging = false;
|
||||||
lastFrameInteracted = false;
|
lastFrameInteracted = false;
|
||||||
// Optionally, you can notify consumers of release if needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTouchPositionPerformed(InputAction.CallbackContext ctx)
|
private void OnTouchPositionPerformed(InputAction.CallbackContext ctx)
|
||||||
{
|
{
|
||||||
Vector2 pos = ctx.ReadValue<Vector2>();
|
// No longer needed, OnTouchHeld will be handled in Update
|
||||||
if (isTouchHeld)
|
|
||||||
{
|
|
||||||
// Convert to world position
|
|
||||||
Vector3 worldPos = Camera.main.ScreenToWorldPoint(pos);
|
|
||||||
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
|
||||||
if (!lastFrameInteracted)
|
|
||||||
defaultConsumer?.OnTouchPress(worldPos2D); // Move continuously to finger position
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// Continuously advertise the last touch position while held
|
if (isPressed && touchPositionAction != null)
|
||||||
if (isTouchHeld && touchPositionAction != null)
|
|
||||||
{
|
{
|
||||||
Vector2 pos = touchPositionAction.ReadValue<Vector2>();
|
Vector2 screenPos = touchPositionAction.ReadValue<Vector2>();
|
||||||
Vector3 worldPos = Camera.main.ScreenToWorldPoint(pos);
|
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
|
||||||
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
||||||
if (!lastFrameInteracted)
|
defaultConsumer?.OnHold(worldPos2D);
|
||||||
defaultConsumer?.OnTouchPress(worldPos2D);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +143,7 @@ public class InputManager : MonoBehaviour
|
|||||||
var interactable = hit.GetComponent<Interactable>();
|
var interactable = hit.GetComponent<Interactable>();
|
||||||
if (interactable != null)
|
if (interactable != null)
|
||||||
{
|
{
|
||||||
interactable.OnTouchPress(worldPos);
|
interactable.OnTap(worldPos);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,19 @@ public class Interactable : MonoBehaviour, ITouchInputConsumer
|
|||||||
stepBehaviour = GetComponent<ObjectiveStepBehaviour>();
|
stepBehaviour = GetComponent<ObjectiveStepBehaviour>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by InputManager when this interactable is clicked/touched
|
// Implement new ITouchInputConsumer contract
|
||||||
public void OnTouchPress(Vector2 worldPosition)
|
public void OnTap(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Defer lock check to follower arrival
|
Debug.Log($"[Interactable] OnTap at {worldPosition} on {gameObject.name}");
|
||||||
Debug.Log($"[Interactable] OnTouchPress at {worldPosition} on {gameObject.name}");
|
|
||||||
StartedInteraction?.Invoke();
|
StartedInteraction?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTouchPosition(Vector2 screenPosition)
|
public void OnDragStart(Vector2 worldPosition) { }
|
||||||
{
|
public void OnDrag(Vector2 worldPosition) { }
|
||||||
// Optionally handle drag/move here
|
public void OnDragEnd(Vector2 worldPosition) { }
|
||||||
}
|
public void OnHoldStart(Vector2 worldPosition) { /* No hold behavior for interactables */ }
|
||||||
|
public void OnHold(Vector2 worldPosition) { /* No hold behavior for interactables */ }
|
||||||
|
public void OnHoldEnd(Vector2 worldPosition) { /* No hold behavior for interactables */ }
|
||||||
|
|
||||||
// Called when the follower arrives at this interactable
|
// Called when the follower arrives at this interactable
|
||||||
public bool OnFollowerArrived(FollowerController follower)
|
public bool OnFollowerArrived(FollowerController follower)
|
||||||
|
|||||||
@@ -17,12 +17,21 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
|||||||
private Animator animator;
|
private Animator animator;
|
||||||
private Transform artTransform;
|
private Transform artTransform;
|
||||||
|
|
||||||
|
// For direct movement mode
|
||||||
|
private Vector3 directMoveVelocity = Vector3.zero;
|
||||||
|
|
||||||
public delegate void ArrivedAtTargetHandler();
|
public delegate void ArrivedAtTargetHandler();
|
||||||
public event ArrivedAtTargetHandler OnArrivedAtTarget;
|
public event ArrivedAtTargetHandler OnArrivedAtTarget;
|
||||||
public event System.Action OnMoveToCancelled;
|
public event System.Action OnMoveToCancelled;
|
||||||
private Coroutine moveToCoroutine;
|
private Coroutine moveToCoroutine;
|
||||||
private bool interruptMoveTo = false;
|
private bool interruptMoveTo = false;
|
||||||
|
|
||||||
|
private bool isDragging = false;
|
||||||
|
private Coroutine pathfindingDragCoroutine; // For pathfinding drag updates
|
||||||
|
private Vector2 lastDragPosition; // Store last drag position
|
||||||
|
private float pathfindingDragUpdateInterval = 0.1f; // Interval in seconds
|
||||||
|
private bool pendingTap = false; // Track if OnHoldEnd is following a tap
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
rb3d = GetComponent<Rigidbody>();
|
rb3d = GetComponent<Rigidbody>();
|
||||||
@@ -49,37 +58,90 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
|||||||
InputManager.Instance?.SetDefaultConsumer(this);
|
InputManager.Instance?.SetDefaultConsumer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEnable()
|
// Implement new ITouchInputConsumer contract
|
||||||
|
public void OnTap(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// No longer register here
|
Debug.Log($"[PlayerTouchController] OnTap at {worldPosition}");
|
||||||
|
pendingTap = true;
|
||||||
|
if (aiPath != null)
|
||||||
|
{
|
||||||
|
aiPath.enabled = true;
|
||||||
|
aiPath.canMove = true;
|
||||||
|
aiPath.isStopped = false;
|
||||||
|
SetTargetPosition(worldPosition);
|
||||||
|
directMoveVelocity = Vector3.zero;
|
||||||
|
isDragging = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove Update and HandleInput
|
// --- Hold-based tracking ---
|
||||||
|
public void OnHoldStart(Vector2 worldPosition)
|
||||||
public void OnTouchPress(Vector2 worldPosition)
|
|
||||||
{
|
{
|
||||||
// If moving to pickup, interrupt
|
pendingTap = false;
|
||||||
InterruptMoveTo();
|
lastDragPosition = worldPosition;
|
||||||
Debug.Log($"PlayerTouchController.OnTouchPress received worldPosition: {worldPosition}");
|
isDragging = true;
|
||||||
SetTargetPosition(worldPosition);
|
if (GameManager.Instance.DefaultHoldMovementMode == GameSettings.HoldMovementMode.Pathfinding && aiPath != null)
|
||||||
|
{
|
||||||
|
aiPath.enabled = true;
|
||||||
|
if (pathfindingDragCoroutine != null) StopCoroutine(pathfindingDragCoroutine);
|
||||||
|
pathfindingDragCoroutine = StartCoroutine(PathfindingDragUpdateCoroutine());
|
||||||
|
}
|
||||||
|
else // Direct movement
|
||||||
|
{
|
||||||
|
if (aiPath != null) aiPath.enabled = false;
|
||||||
|
directMoveVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTouchPosition(Vector2 screenPosition)
|
public void OnHold(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
Debug.Log($"PlayerTouchController.OnTouchPosition called with screenPosition: {screenPosition}");
|
if (!isDragging) return;
|
||||||
// Optionally handle drag/move here
|
lastDragPosition = worldPosition;
|
||||||
|
if (GameManager.Instance.DefaultHoldMovementMode == GameSettings.HoldMovementMode.Direct)
|
||||||
|
{
|
||||||
|
if (aiPath != null && aiPath.enabled) aiPath.enabled = false;
|
||||||
|
MoveDirectlyTo(worldPosition);
|
||||||
|
}
|
||||||
|
// If pathfinding, coroutine will update destination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnHoldEnd(Vector2 worldPosition)
|
||||||
|
{
|
||||||
|
isDragging = false;
|
||||||
|
directMoveVelocity = Vector3.zero;
|
||||||
|
if (aiPath != null && GameManager.Instance.DefaultHoldMovementMode == GameSettings.HoldMovementMode.Pathfinding)
|
||||||
|
{
|
||||||
|
if (pathfindingDragCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(pathfindingDragCoroutine);
|
||||||
|
pathfindingDragCoroutine = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Only disable aiPath in direct mode if this was a hold/drag, not a tap
|
||||||
|
if (aiPath != null && GameManager.Instance.DefaultHoldMovementMode == GameSettings.HoldMovementMode.Direct && !pendingTap)
|
||||||
|
{
|
||||||
|
aiPath.enabled = false;
|
||||||
|
}
|
||||||
|
pendingTap = false; // Reset after handling
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Drag methods are now no-ops for movement tracking ---
|
||||||
|
public void OnDragStart(Vector2 worldPosition) { }
|
||||||
|
public void OnDrag(Vector2 worldPosition) { }
|
||||||
|
public void OnDragEnd(Vector2 worldPosition) { }
|
||||||
|
|
||||||
void SetTargetPosition(Vector2 worldPosition)
|
void SetTargetPosition(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
Debug.Log($"PlayerTouchController.SetTargetPosition: worldPosition={worldPosition}");
|
Debug.Log($"[PlayerTouchController] SetTargetPosition: worldPosition={worldPosition}");
|
||||||
targetPosition = new Vector3(worldPosition.x, worldPosition.y, transform.position.z);
|
targetPosition = new Vector3(worldPosition.x, worldPosition.y, transform.position.z);
|
||||||
hasTarget = true;
|
hasTarget = true;
|
||||||
if (aiPath != null)
|
if (aiPath != null)
|
||||||
{
|
{
|
||||||
aiPath.destination = targetPosition;
|
aiPath.destination = targetPosition;
|
||||||
aiPath.maxSpeed = GameManager.Instance.MoveSpeed;
|
aiPath.maxSpeed = GameManager.Instance.MoveSpeed;
|
||||||
Debug.Log($"AIPath destination set to {targetPosition}");
|
aiPath.canMove = true;
|
||||||
|
aiPath.isStopped = false;
|
||||||
|
Debug.Log($"[PlayerTouchController] AIPath destination set to {targetPosition}, canMove={aiPath.canMove}, isStopped={aiPath.isStopped}, enabled={aiPath.enabled}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -87,12 +149,41 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MoveDirectlyTo(Vector2 worldPosition)
|
||||||
|
{
|
||||||
|
if (aiPath == null) return;
|
||||||
|
Vector3 current = transform.position;
|
||||||
|
Vector3 target = new Vector3(worldPosition.x, worldPosition.y, current.z);
|
||||||
|
Vector3 toTarget = (target - current);
|
||||||
|
Vector3 direction = toTarget.normalized;
|
||||||
|
float maxSpeed = aiPath.maxSpeed;
|
||||||
|
float acceleration = aiPath.maxAcceleration;
|
||||||
|
// Accelerate velocity toward target direction
|
||||||
|
directMoveVelocity = Vector3.MoveTowards(directMoveVelocity, direction * maxSpeed, acceleration * Time.deltaTime);
|
||||||
|
// Clamp velocity to max speed
|
||||||
|
if (directMoveVelocity.magnitude > maxSpeed)
|
||||||
|
directMoveVelocity = directMoveVelocity.normalized * maxSpeed;
|
||||||
|
// Move the player
|
||||||
|
Vector3 move = directMoveVelocity * Time.deltaTime;
|
||||||
|
// Don't overshoot the target
|
||||||
|
if (move.magnitude > toTarget.magnitude)
|
||||||
|
move = toTarget;
|
||||||
|
transform.position += move;
|
||||||
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// Update animator speed parameter
|
|
||||||
if (animator != null && aiPath != null)
|
if (animator != null && aiPath != null)
|
||||||
{
|
{
|
||||||
float normalizedSpeed = aiPath.velocity.magnitude / aiPath.maxSpeed;
|
float normalizedSpeed = 0f;
|
||||||
|
if (isDragging)
|
||||||
|
{
|
||||||
|
normalizedSpeed = directMoveVelocity.magnitude / aiPath.maxSpeed;
|
||||||
|
}
|
||||||
|
else if (aiPath.enabled)
|
||||||
|
{
|
||||||
|
normalizedSpeed = aiPath.velocity.magnitude / aiPath.maxSpeed;
|
||||||
|
}
|
||||||
animator.SetFloat("Speed", Mathf.Clamp01(normalizedSpeed));
|
animator.SetFloat("Speed", Mathf.Clamp01(normalizedSpeed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,6 +204,9 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
|||||||
public void InterruptMoveTo()
|
public void InterruptMoveTo()
|
||||||
{
|
{
|
||||||
interruptMoveTo = true;
|
interruptMoveTo = true;
|
||||||
|
isDragging = false;
|
||||||
|
directMoveVelocity = Vector3.zero;
|
||||||
|
if (GameManager.Instance.DefaultHoldMovementMode == GameSettings.HoldMovementMode.Direct && aiPath != null) aiPath.enabled = false;
|
||||||
OnMoveToCancelled?.Invoke();
|
OnMoveToCancelled?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,4 +237,16 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
|||||||
OnArrivedAtTarget?.Invoke();
|
OnArrivedAtTarget?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private System.Collections.IEnumerator PathfindingDragUpdateCoroutine()
|
||||||
|
{
|
||||||
|
Debug.Log("[PlayerTouchController] PathfindingDragUpdateCoroutine started");
|
||||||
|
while (isDragging && aiPath != null)
|
||||||
|
{
|
||||||
|
aiPath.destination = new Vector3(lastDragPosition.x, lastDragPosition.y, transform.position.z);
|
||||||
|
Debug.Log($"[PlayerTouchController] Updating aiPath.destination to {aiPath.destination}");
|
||||||
|
yield return new WaitForSeconds(pathfindingDragUpdateInterval);
|
||||||
|
}
|
||||||
|
Debug.Log("[PlayerTouchController] PathfindingDragUpdateCoroutine stopped");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user