119 lines
3.1 KiB
C#
119 lines
3.1 KiB
C#
using UnityEngine;
|
|
|
|
namespace UnityStandardAssets.Utility
|
|
{
|
|
public class WaypointProgressTracker : MonoBehaviour
|
|
{
|
|
public enum ProgressStyle
|
|
{
|
|
SmoothAlongRoute = 0,
|
|
PointToPoint = 1
|
|
}
|
|
|
|
[SerializeField]
|
|
private WaypointCircuit circuit;
|
|
|
|
[SerializeField]
|
|
private float lookAheadForTargetOffset = 5f;
|
|
|
|
[SerializeField]
|
|
private float lookAheadForTargetFactor = 0.1f;
|
|
|
|
[SerializeField]
|
|
private float lookAheadForSpeedOffset = 10f;
|
|
|
|
[SerializeField]
|
|
private float lookAheadForSpeedFactor = 0.2f;
|
|
|
|
[SerializeField]
|
|
private ProgressStyle progressStyle;
|
|
|
|
[SerializeField]
|
|
private float pointToPointThreshold = 4f;
|
|
|
|
public Transform target;
|
|
|
|
private float progressDistance;
|
|
|
|
private int progressNum;
|
|
|
|
private Vector3 lastPosition;
|
|
|
|
private float speed;
|
|
|
|
public WaypointCircuit.RoutePoint targetPoint { get; private set; }
|
|
|
|
public WaypointCircuit.RoutePoint speedPoint { get; private set; }
|
|
|
|
public WaypointCircuit.RoutePoint progressPoint { get; private set; }
|
|
|
|
private void Start()
|
|
{
|
|
if (target == null)
|
|
{
|
|
target = new GameObject(base.name + " Waypoint Target").transform;
|
|
}
|
|
Reset();
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
progressDistance = 0f;
|
|
progressNum = 0;
|
|
if (progressStyle == ProgressStyle.PointToPoint)
|
|
{
|
|
target.position = circuit.Waypoints[progressNum].position;
|
|
target.rotation = circuit.Waypoints[progressNum].rotation;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (progressStyle == ProgressStyle.SmoothAlongRoute)
|
|
{
|
|
if (Time.deltaTime > 0f)
|
|
{
|
|
speed = Mathf.Lerp(speed, (lastPosition - base.transform.position).magnitude / Time.deltaTime, Time.deltaTime);
|
|
}
|
|
target.position = circuit.GetRoutePoint(progressDistance + lookAheadForTargetOffset + lookAheadForTargetFactor * speed).position;
|
|
target.rotation = Quaternion.LookRotation(circuit.GetRoutePoint(progressDistance + lookAheadForSpeedOffset + lookAheadForSpeedFactor * speed).direction);
|
|
progressPoint = circuit.GetRoutePoint(progressDistance);
|
|
Vector3 lhs = progressPoint.position - base.transform.position;
|
|
if (Vector3.Dot(lhs, progressPoint.direction) < 0f)
|
|
{
|
|
progressDistance += lhs.magnitude * 0.5f;
|
|
}
|
|
lastPosition = base.transform.position;
|
|
}
|
|
else
|
|
{
|
|
if ((target.position - base.transform.position).magnitude < pointToPointThreshold)
|
|
{
|
|
progressNum = (progressNum + 1) % circuit.Waypoints.Length;
|
|
}
|
|
target.position = circuit.Waypoints[progressNum].position;
|
|
target.rotation = circuit.Waypoints[progressNum].rotation;
|
|
progressPoint = circuit.GetRoutePoint(progressDistance);
|
|
Vector3 lhs2 = progressPoint.position - base.transform.position;
|
|
if (Vector3.Dot(lhs2, progressPoint.direction) < 0f)
|
|
{
|
|
progressDistance += lhs2.magnitude;
|
|
}
|
|
lastPosition = base.transform.position;
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (Application.isPlaying)
|
|
{
|
|
Gizmos.color = Color.green;
|
|
Gizmos.DrawLine(base.transform.position, target.position);
|
|
Gizmos.DrawWireSphere(circuit.GetRoutePosition(progressDistance), 1f);
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawLine(target.position, target.position + target.forward);
|
|
}
|
|
}
|
|
}
|
|
}
|