85 lines
3.0 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|