This commit is contained in:
2025-09-02 13:49:21 +02:00
5 changed files with 176 additions and 25 deletions

View File

@@ -15,9 +15,9 @@ GameObject:
- component: {fileID: 2999879259114430221}
- component: {fileID: 7393789300602426170}
- component: {fileID: 1676944588148945034}
m_Layer: 0
m_Layer: 7
m_Name: PlayerCharacter
m_TagString: Untagged
m_TagString: Player
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
@@ -221,6 +221,10 @@ PrefabInstance:
propertyPath: m_Name
value: Trafalgar
objectReference: {fileID: 0}
- target: {fileID: 784715772773378889, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
propertyPath: m_Layer
value: 7
objectReference: {fileID: 0}
- target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
propertyPath: m_LocalScale.x
value: 0.5

View File

@@ -495,11 +495,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.x
value: -4.53
value: -8.54
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.y
value: -0.5
value: -1.01
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.z
@@ -552,11 +552,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.x
value: 4.49
value: 5.6
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.y
value: 3.49
value: 4.5
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.z
@@ -614,11 +614,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.x
value: -1.42
value: -4.43
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.y
value: 3.37
value: 6.43
objectReference: {fileID: 0}
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
propertyPath: m_LocalPosition.z
@@ -22743,11 +22743,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
propertyPath: m_LocalPosition.x
value: -3.03
value: -2.83
objectReference: {fileID: 0}
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
propertyPath: m_LocalPosition.y
value: -1.2
value: -1.89
objectReference: {fileID: 0}
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
propertyPath: m_LocalPosition.z

View File

@@ -1 +1,148 @@

using UnityEngine;
using Pathfinding;
public class FollowerController : MonoBehaviour
{
[Header("Follower Settings")]
public float followDistance = 1.5f; // Desired distance behind player
public bool debugDrawTarget = true;
public float followUpdateInterval = 0.1f; // How often to update follow logic
public float manualMoveSmooth = 8f; // Smoothing factor for manual movement
private Transform playerTransform;
private AIPath playerAIPath;
private AIPath aiPath;
private Vector3 targetPoint;
private float timer;
private bool usePathfinding = false;
private bool isManualFollowing = true; // Default to manual following
private Vector3 lastMoveDir = Vector3.right; // Default direction
private float currentSpeed = 0f;
[Header("Speed Settings")]
public float acceleration = 10f;
public float deceleration = 12f;
public float thresholdFar = 2.5f;
public float thresholdNear = 0.5f;
public float stopThreshold = 0.1f; // Stop moving when within this distance
private float playerMaxSpeed = 5f;
void Awake()
{
aiPath = GetComponent<AIPath>();
}
void Start()
{
// Find player by tag
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
if (playerObj != null)
{
playerTransform = playerObj.transform;
playerAIPath = playerObj.GetComponent<AIPath>();
// Fetch player's max speed
if (playerAIPath != null)
{
playerMaxSpeed = playerAIPath.maxSpeed;
}
}
else
{
Debug.LogError("FollowerController: Player object with tag 'Player' not found.");
}
}
void UpdateFollowTarget()
{
// 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;
}
}
void Update()
{
if (playerTransform == null)
return;
timer += Time.deltaTime;
if (timer >= followUpdateInterval)
{
timer = 0f;
UpdateFollowTarget();
}
// Manual movement logic with acceleration/deceleration and stop threshold
if (isManualFollowing)
{
float dist = Vector3.Distance(transform.position, targetPoint);
if (dist > stopThreshold)
{
float desiredSpeed = playerMaxSpeed;
if (dist > thresholdFar)
{
// Accelerate to player's max speed
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, playerMaxSpeed);
}
else if (dist <= thresholdNear && dist > stopThreshold)
{
// Decelerate as approaching target, but keep moving until stopThreshold
desiredSpeed = Mathf.Max(currentSpeed - deceleration * Time.deltaTime, 0.5f);
}
else
{
// Maintain player's max speed
desiredSpeed = playerMaxSpeed;
}
currentSpeed = desiredSpeed;
Vector3 dir = (targetPoint - transform.position).normalized;
transform.position += dir * currentSpeed * Time.deltaTime;
}
else
{
// Stop moving when close enough
currentSpeed = 0f;
}
}
}
// Command follower to go to a specific point (pathfinding mode)
public void GoToPoint(Vector2 worldPosition)
{
isManualFollowing = false;
if (aiPath != null)
{
aiPath.enabled = true;
aiPath.destination = new Vector3(worldPosition.x, worldPosition.y, 0);
}
}
void OnDrawGizmos()
{
if (debugDrawTarget && Application.isPlaying)
{
Gizmos.color = Color.cyan;
Gizmos.DrawSphere(targetPoint, 0.2f);
Gizmos.color = Color.yellow;
Gizmos.DrawLine(transform.position, targetPoint);
}
}
}