[Player][Interactions] Pulver moves to item and goes back. Item disappears, but in wrong order

This commit is contained in:
Michal Pikulski
2025-09-04 00:00:46 +02:00
parent 97c5edf619
commit 0c930d09a4
18 changed files with 455 additions and 43 deletions

View File

@@ -27,6 +27,9 @@ public class FollowerController : MonoBehaviour
public float thresholdNear = 0.5f;
public float stopThreshold = 0.1f; // Stop moving when within this distance
private float playerMaxSpeed = 5f;
private const float followerSpeedMultiplier = 1.2f;
private float followerMaxSpeed = 6f; // Default, will be set from player
private float defaultFollowerMaxSpeed = 6f; // Default fallback value
private Animator animator;
private Transform artTransform;
@@ -72,6 +75,8 @@ public class FollowerController : MonoBehaviour
if (playerAIPath != null)
{
playerMaxSpeed = playerAIPath.maxSpeed;
defaultFollowerMaxSpeed = playerMaxSpeed;
followerMaxSpeed = playerMaxSpeed * followerSpeedMultiplier;
}
}
else
@@ -95,27 +100,29 @@ public class FollowerController : MonoBehaviour
if (playerTransform == null)
return; // Still missing, skip update
}
// Determine direction: use player's velocity if available, else lastMoveDir
Vector3 playerPos = playerTransform.position;
Vector3 moveDir = Vector3.zero;
if (playerAIPath != null && playerAIPath.velocity.magnitude > 0.01f)
if (isManualFollowing)
{
moveDir = playerAIPath.velocity.normalized;
lastMoveDir = moveDir; // Update last valid direction
}
else
{
moveDir = lastMoveDir; // Use last direction if stationary
}
// Calculate target point behind player
targetPoint = playerPos - moveDir * followDistance;
targetPoint.z = 0; // For 2D
// Determine direction: use player's velocity if available, else lastMoveDir
Vector3 playerPos = playerTransform.position;
Vector3 moveDir = Vector3.zero;
if (playerAIPath != null && playerAIPath.velocity.magnitude > 0.01f)
{
moveDir = playerAIPath.velocity.normalized;
lastMoveDir = moveDir; // Update last valid direction
}
else
{
moveDir = lastMoveDir; // Use last direction if stationary
}
// Calculate target point behind player
targetPoint = playerPos - moveDir * followDistance;
targetPoint.z = 0; // For 2D
// Always use manual following unless GoToPoint is called
isManualFollowing = true;
if (aiPath != null)
{
aiPath.enabled = false;
// Only disable aiPath if in manual mode
if (aiPath != null)
{
aiPath.enabled = false;
}
}
}
@@ -139,14 +146,17 @@ public class FollowerController : MonoBehaviour
// Manual movement logic with acceleration/deceleration and stop threshold
if (isManualFollowing)
{
float dist = Vector3.Distance(transform.position, targetPoint);
// 2D distance calculation (ignore z)
Vector2 current2D = new Vector2(transform.position.x, transform.position.y);
Vector2 target2D = new Vector2(targetPoint.x, targetPoint.y);
float dist = Vector2.Distance(current2D, target2D);
if (dist > stopThreshold)
{
float desiredSpeed = playerMaxSpeed;
float desiredSpeed = followerMaxSpeed;
if (dist > thresholdFar)
{
// Accelerate to player's max speed
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, playerMaxSpeed);
// Accelerate to follower's max speed
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, followerMaxSpeed);
}
else if (dist <= thresholdNear && dist > stopThreshold)
{
@@ -155,8 +165,8 @@ public class FollowerController : MonoBehaviour
}
else
{
// Maintain player's max speed
desiredSpeed = playerMaxSpeed;
// Maintain follower's max speed
desiredSpeed = followerMaxSpeed;
}
currentSpeed = desiredSpeed;
Vector3 dir = (targetPoint - transform.position).normalized;
@@ -176,12 +186,12 @@ public class FollowerController : MonoBehaviour
if (isManualFollowing)
{
// Use currentSpeed for manual following
normalizedSpeed = currentSpeed / playerMaxSpeed;
normalizedSpeed = currentSpeed / followerMaxSpeed;
}
else if (aiPath != null)
{
// Use aiPath velocity for pathfinding mode
normalizedSpeed = aiPath.velocity.magnitude / playerMaxSpeed;
normalizedSpeed = aiPath.velocity.magnitude / followerMaxSpeed;
}
animator.SetFloat("Speed", Mathf.Clamp01(normalizedSpeed));
}
@@ -194,10 +204,64 @@ public class FollowerController : MonoBehaviour
if (aiPath != null)
{
aiPath.enabled = true;
aiPath.maxSpeed = followerMaxSpeed;
aiPath.destination = new Vector3(worldPosition.x, worldPosition.y, 0);
}
}
public delegate void FollowerPickupHandler();
public event FollowerPickupHandler OnPickupArrived;
public event FollowerPickupHandler OnPickupReturned;
private Coroutine pickupCoroutine;
// Command follower to go to a specific point and return to player
public void GoToPointAndReturn(Vector2 itemPosition, Transform playerTransform)
{
if (pickupCoroutine != null)
StopCoroutine(pickupCoroutine);
if (aiPath != null)
aiPath.maxSpeed = followerMaxSpeed;
pickupCoroutine = StartCoroutine(PickupSequence(itemPosition, playerTransform));
}
private System.Collections.IEnumerator PickupSequence(Vector2 itemPosition, Transform playerTransform)
{
isManualFollowing = false;
if (aiPath != null)
{
aiPath.enabled = true;
aiPath.maxSpeed = followerMaxSpeed;
aiPath.destination = new Vector3(itemPosition.x, itemPosition.y, 0);
}
// Wait until follower reaches item (2D distance)
while (Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(itemPosition.x, itemPosition.y)) > stopThreshold)
{
yield return null;
}
OnPickupArrived?.Invoke();
// Wait briefly, then return to player
yield return new WaitForSeconds(0.2f);
if (aiPath != null && playerTransform != null)
{
aiPath.maxSpeed = followerMaxSpeed;
aiPath.destination = playerTransform.position;
}
// Wait until follower returns to player (2D distance)
while (playerTransform != null && Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(playerTransform.position.x, playerTransform.position.y)) > stopThreshold)
{
yield return null;
}
OnPickupReturned?.Invoke();
// Reset follower speed to normal after pickup
followerMaxSpeed = defaultFollowerMaxSpeed;
if (aiPath != null)
aiPath.maxSpeed = followerMaxSpeed;
isManualFollowing = true;
if (aiPath != null)
aiPath.enabled = false;
pickupCoroutine = null;
}
void OnDrawGizmos()
{
if (debugDrawTarget && Application.isPlaying)