|
using e23.VehicleController; |
|
using UnityEngine; |
|
using UnityEngine.AI; |
|
|
|
public class ExampleAINavMesh : MonoBehaviour |
|
{ |
|
[SerializeField] private Transform target; |
|
[SerializeField] private bool canDrive = false; |
|
[SerializeField] private float minimalDistanceToNextWaypoint = 0.05f; |
|
|
|
private VehicleBehaviour vehicleBehaviour; |
|
private int targetWaypointIndex = 0; |
|
private Vector3 targetWaypoint; |
|
private int newDirection; |
|
private bool brake = false; |
|
|
|
private NavMeshPath path; |
|
private float elapsed = 0f; |
|
|
|
private void Start() |
|
{ |
|
GetRequiredComponents(); |
|
GetFirstWaypoint(); |
|
} |
|
|
|
private void Update() |
|
{ |
|
elapsed += Time.deltaTime; |
|
if (elapsed > 1.0f) |
|
{ |
|
elapsed = 0f; |
|
CalculatePath(); |
|
} |
|
|
|
for (int i = 0; i < path.corners.Length - 1; i++) |
|
{ Debug.DrawLine(path.corners[i], path.corners[i + 1], Color.red); } |
|
|
|
if (canDrive == true) |
|
{ |
|
EvaluateNextWaypoint(); |
|
if (DistanceToWaypoint() < (minimalDistanceToNextWaypoint * 2.5f)) |
|
{ |
|
Drive(false); |
|
} |
|
else |
|
{ |
|
Drive(true); |
|
} |
|
SteerToWaypoint(); |
|
|
|
if (DistanceToTarget() < minimalDistanceToNextWaypoint) |
|
{ |
|
canDrive = false; |
|
} |
|
|
|
} |
|
} |
|
|
|
private void GetRequiredComponents() |
|
{ |
|
vehicleBehaviour = GetComponent<VehicleBehaviour>(); |
|
path = new NavMeshPath(); |
|
CalculatePath(); |
|
} |
|
|
|
private void GetFirstWaypoint() |
|
{ |
|
targetWaypoint = path.corners[1]; |
|
} |
|
|
|
private void Drive(bool forward) |
|
{ |
|
if (forward) { vehicleBehaviour.ControlAcceleration(); } |
|
else { vehicleBehaviour.ControlBrake(); } |
|
} |
|
|
|
private void CalculatePath() |
|
{ |
|
NavMesh.CalculatePath(transform.position, target.position, NavMesh.AllAreas, path); |
|
} |
|
|
|
private void SteerToWaypoint() |
|
{ |
|
Vector3 targetVector = targetWaypoint - transform.position; |
|
targetVector.y = transform.localPosition.y; |
|
|
|
Vector3 transformForwardPlane = transform.forward; |
|
transformForwardPlane.y = transform.localPosition.y; |
|
|
|
Vector3 cross = Vector3.Cross(transformForwardPlane, targetVector); |
|
|
|
newDirection = cross.y >= 0 ? 1 : -1; |
|
|
|
SteerVehicle(newDirection); |
|
} |
|
|
|
private void SteerVehicle(int direction) |
|
{ |
|
vehicleBehaviour.ControlTurning(direction); |
|
} |
|
|
|
private void EvaluateNextWaypoint() |
|
{ |
|
var distanceToWaypoint = DistanceToWaypoint(); |
|
|
|
if (distanceToWaypoint < minimalDistanceToNextWaypoint) |
|
{ |
|
CalculatePath(); |
|
targetWaypointIndex = 1; |
|
targetWaypoint = path.corners[targetWaypointIndex]; |
|
} |
|
} |
|
|
|
private float DistanceToWaypoint() |
|
{ |
|
Vector2 target = new Vector2(targetWaypoint.x, targetWaypoint.z); |
|
Vector2 position = new Vector2(transform.position.x, transform.position.z); |
|
|
|
return Vector2.Distance(target, position); |
|
} |
|
|
|
private float DistanceToTarget() |
|
{ |
|
Vector2 endTarget = new Vector2(target.position.x, target.position.z); |
|
Vector2 position = new Vector2(transform.position.x, transform.position.z); |
|
|
|
return Vector2.Distance(endTarget, position); |
|
} |
|
} |