Files
FueraDeEscala/Assets/Game Kit Controller/Scripts/Vehicles/AI/WaypointProgressTracker.cs
Robii Aragon fd87a6ffd5 add ckg
plantilla base para movimiento básico
2026-02-05 05:07:55 -08:00

268 lines
7.2 KiB
C#

using System;
using UnityEngine;
public class WaypointProgressTracker : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool waypointActive;
// This script can be used with any object that is supposed to follow a
// route marked out by waypoints.
// This script manages the amount to look ahead along the route,
// and keeps track of progress and laps.
[SerializeField] float lookAheadForTargetOffset = 5;
// The offset ahead along the route that the we will aim for
[SerializeField] float lookAheadForTargetFactor = .1f;
// A multiplier adding distance ahead along the route to aim for, based on current speed
[SerializeField] float lookAheadForSpeedOffset = 10;
// The offset ahead only the route for speed adjustments (applied as the rotation of the waypoint target transform)
[SerializeField] float lookAheadForSpeedFactor = .2f;
// A multiplier adding distance ahead along the route for speed adjustments
[SerializeField] ProgressStyle progressStyle = ProgressStyle.SmoothAlongRoute;
// whether to update the position smoothly along the route (good for curved paths) or just when we reach each waypoint.
[SerializeField] float pointToPointThreshold = 4;
// proximity to waypoint which must be reached to switch target to next waypoint : only used in PointToPoint mode.
public enum ProgressStyle
{
SmoothAlongRoute,
PointToPoint,
}
// these are public, readable by other objects - i.e. for an AI to know where to head!
public WaypointCircuit.RoutePoint targetPoint { get; set; }
public WaypointCircuit.RoutePoint speedPoint { get; set; }
public WaypointCircuit.RoutePoint progressPoint { get; set; }
[Space]
[Header ("Debug")]
[Space]
public bool showGizmo;
public float progressDistance;
// The progress round the route, used in smooth mode.
public int progressNum;
// the current waypoint number, used in point-to-point mode.
[Space]
[Header ("Components")]
[Space]
public vehicleAINavMesh vehicleAI;
public Transform target;
[SerializeField] WaypointCircuit circuit;
public Transform vehicleTransform;
// A reference to the waypoint-based route we should follow
Vector3 lastPosition;
// Used to calculate current speed (since we may not have a rigidbody component)
float speed;
// current speed of this object (calculated from delta since last frame)
// setup script properties
Transform currentWaypoint;
Vector3 currentVehiclePosition;
void Start ()
{
// we use a transform to represent the point to aim for, and the point which
// is considered for upcoming changes-of-speed. This allows this component
// to communicate this information to the AI without requiring further dependencies.
// You can manually create a transform and assign it to this component *and* the AI,
// then this component will update it, and the AI can read it.
if (waypointActive) {
setTrackActiveState (true);
}
}
public void setWaypointActiveState (bool state)
{
waypointActive = state;
if (waypointActive) {
setTrackActiveState (true);
} else {
setTrackActiveState (false);
}
}
public void activateTrackState ()
{
if (!waypointActive) {
setTrackActiveState (true);
}
}
public void stopTrackState ()
{
if (waypointActive) {
setTrackActiveState (false);
}
}
void setTrackActiveState (bool state)
{
bool circuitLocated = circuit != null;
if (!circuitLocated) {
circuit = FindObjectOfType<WaypointCircuit> ();
circuitLocated = circuit != null;
}
if (!circuitLocated) {
state = false;
waypointActive = false;
}
if (state) {
resetTrackerState ();
if (circuit == null) {
circuit = FindObjectOfType<WaypointCircuit> ();
}
if (vehicleTransform == null) {
vehicleTransform = transform;
}
if (vehicleAI.useNavmeshActive) {
vehicleAI.follow (target);
}
vehicleAI.setDrivingState (true);
vehicleAI.setUsingTrackActive (true);
} else {
vehicleAI.setDrivingState (false);
vehicleAI.setUsingTrackActive (false);
}
}
// reset the object to sensible values
public void resetTrackerState ()
{
bool circuitLocated = circuit != null;
if (!circuitLocated) {
return;
}
if (progressStyle == ProgressStyle.PointToPoint) {
target.position = circuit.waypointList [progressNum].position;
target.rotation = circuit.waypointList [progressNum].rotation;
} else {
target.position = vehicleTransform.position;
target.rotation = vehicleTransform.rotation;
// Vector3 currentPosition = circuit.getClosestPosition (vehicleTransform.position);
// progressDistance = currentPosition.magnitude * 0.5f;
progressDistance = circuit.getProgressValue (vehicleTransform.position);
}
}
void Update ()
{
if (waypointActive) {
currentVehiclePosition = vehicleTransform.position;
if (progressStyle == ProgressStyle.SmoothAlongRoute) {
// determine the position we should currently be aiming for
// (this is different to the current progress position, it is a a certain amount ahead along the route)
// we use lerp as a simple way of smoothing out the speed over time.
if (Time.deltaTime > 0) {
speed = Mathf.Lerp (speed, (lastPosition - currentVehiclePosition).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);
// get our current progress along the route
progressPoint = circuit.GetRoutePoint (progressDistance);
Vector3 progressDelta = progressPoint.position - currentVehiclePosition;
if (Vector3.Dot (progressDelta, progressPoint.direction) < 0) {
progressDistance += progressDelta.magnitude * 0.5f;
}
lastPosition = currentVehiclePosition;
} else {
// point to point mode. Just increase the waypoint if we're close enough:
Vector3 targetDelta = target.position - currentVehiclePosition;
if (targetDelta.magnitude < pointToPointThreshold) {
progressNum = (progressNum + 1) % circuit.waypointList.Count;
}
currentWaypoint = circuit.waypointList [progressNum];
target.position = currentWaypoint.position;
target.rotation = currentWaypoint.rotation;
// get our current progress along the route
progressPoint = circuit.GetRoutePoint (progressDistance);
Vector3 progressDelta = progressPoint.position - currentVehiclePosition;
if (Vector3.Dot (progressDelta, progressPoint.direction) < 0) {
progressDistance += progressDelta.magnitude;
}
lastPosition = currentVehiclePosition;
}
}
}
void OnDrawGizmos ()
{
if (!showGizmo) {
return;
}
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
DrawGizmos ();
}
}
void OnDrawGizmosSelected ()
{
DrawGizmos ();
}
//draw the pivot and the final positions of every door
void DrawGizmos ()
{
if (showGizmo) {
if (Application.isPlaying) {
Gizmos.color = Color.green;
Gizmos.DrawLine (vehicleTransform.position, target.position);
Gizmos.DrawWireSphere (circuit.GetRoutePosition (progressDistance), 1);
Gizmos.color = Color.yellow;
Gizmos.DrawLine (target.position, target.position + target.forward);
}
}
}
}