RoadRunner/Assets/ObjectFollowPath.cs
2025-01-29 22:55:46 +01:00

85 lines
3.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectFollowPath : MonoBehaviour
{
[Header("Path Settings")]
public Transform[] waypoints; // Array of waypoints
public float maxSpeed = 5f; // Maximum movement speed
public float acceleration = 2f; // Acceleration rate
public float deceleration = 2f; // Deceleration rate
public float reachThreshold = 0.1f; // Distance to consider the waypoint reached
private int currentWaypointIndex = 0;
private float currentSpeed = 0f; // Current speed
void Update()
{
if (waypoints.Length == 0)
{
Debug.LogWarning("No waypoints assigned to the path!");
return;
}
MoveTowardsWaypoint();
}
void MoveTowardsWaypoint()
{
// Get the current target waypoint
Transform targetWaypoint = waypoints[currentWaypointIndex];
// Calculate distance to target
float distance = Vector3.Distance(transform.position, targetWaypoint.position);
// Adjust speed based on distance (accelerate and decelerate smoothly)
if (distance > reachThreshold * 2)
{
currentSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, maxSpeed);
}
else
{
currentSpeed = Mathf.Max(currentSpeed - deceleration * Time.deltaTime, 0f);
}
// Move towards the target waypoint
Vector3 direction = (targetWaypoint.position - transform.position).normalized;
transform.position += direction * currentSpeed * Time.deltaTime;
// Rotate smoothly to match the Y rotation of the target waypoint
Vector3 currentEulerAngles = transform.rotation.eulerAngles;
float targetZRotation = targetWaypoint.rotation.eulerAngles.z;
transform.rotation = Quaternion.Euler(currentEulerAngles.x, currentEulerAngles.y, Mathf.LerpAngle(currentEulerAngles.z, targetZRotation, Time.deltaTime * currentSpeed));
// Check if the object is close enough to the waypoint
if (distance <= reachThreshold)
{
// Move to the next waypoint
currentWaypointIndex++;
// Teleport back to the first waypoint if we reach the end of the path
if (currentWaypointIndex >= waypoints.Length)
{
transform.position = waypoints[0].position;
currentWaypointIndex = 0;
}
}
}
void OnDrawGizmos()
{
// Draw lines between waypoints in the editor for visualization
if (waypoints != null && waypoints.Length > 1)
{
Gizmos.color = Color.cyan;
for (int i = 0; i < waypoints.Length - 1; i++)
{
Gizmos.DrawLine(waypoints[i].position, waypoints[i + 1].position);
}
// Optionally connect the last waypoint back to the first to show a loop
Gizmos.DrawLine(waypoints[waypoints.Length - 1].position, waypoints[0].position);
}
}
}