93 lines
3.5 KiB
C#
93 lines
3.5 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using Pathfinding;
|
|
using Pathfinding.Drawing;
|
|
using UnityEngine;
|
|
using Vector2 = UnityEngine.Vector2;
|
|
using Vector3 = UnityEngine.Vector3;
|
|
|
|
namespace Reset.Units{
|
|
[RequireComponent(typeof(Seeker))]
|
|
public class UnitPathfinding : UnitComponent, IUnitDirectionProvider{
|
|
public Vector2 Direction{ get; set; }
|
|
|
|
public bool pathfindingEnabled;
|
|
|
|
public Seeker seeker;
|
|
|
|
public float nextWaypointDistance = 3;
|
|
private int currentWaypoint;
|
|
|
|
public Path path;
|
|
public bool reachedEndOfPath;
|
|
|
|
public void Start(){
|
|
seeker = GetComponent<Seeker>();
|
|
|
|
Enemy thisEnemy = (Unit as Enemy);
|
|
|
|
if (thisEnemy.relatedSpawner){
|
|
seeker.graphMask = GraphMask.FromGraph(thisEnemy.relatedSpawner.relatedGraph);
|
|
} else {
|
|
Debug.LogWarning("Creating a graph for a singular enemy is not yet implemented. Graph mask not set on this unit.", transform);
|
|
}
|
|
}
|
|
|
|
public void AssignNewPath(Path p){
|
|
if (!p.error) {
|
|
path = p;
|
|
// Reset the waypoint counter so that we start to move towards the first point in the path
|
|
currentWaypoint = 0;
|
|
}
|
|
}
|
|
|
|
public void Update(){
|
|
FollowCurrentPath();
|
|
}
|
|
|
|
private void FollowCurrentPath(){
|
|
if (path == null) {
|
|
// We have no path to follow yet, so don't do anything
|
|
return;
|
|
}
|
|
|
|
reachedEndOfPath = false;
|
|
// The distance to the next waypoint in the path
|
|
float distanceToWaypoint;
|
|
|
|
while (true) {
|
|
// If you want maximum performance you can check the squared distance instead to get rid of a
|
|
// square root calculation. But that is outside the scope of this tutorial.
|
|
distanceToWaypoint = Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]);
|
|
if (distanceToWaypoint < nextWaypointDistance) {
|
|
// Check if there is another waypoint or if we have reached the end of the path
|
|
if (currentWaypoint + 1 < path.vectorPath.Count) {
|
|
currentWaypoint++;
|
|
} else {
|
|
// Set a status variable to indicate that the agent has reached the end of the path.
|
|
// You can use this to trigger some special code if your game requires that.
|
|
reachedEndOfPath = true;
|
|
|
|
break;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Pass the direction to the direction handler interface
|
|
if (currentWaypoint + 1 == path.vectorPath.Count) {
|
|
Direction = (path.vectorPath[currentWaypoint] - transform.position).ToVector2();
|
|
Direction = Vector3.ClampMagnitude(Direction, 1f);
|
|
} else {
|
|
Direction = (path.vectorPath[currentWaypoint] - transform.position).normalized.ToVector2();
|
|
}
|
|
|
|
// Draw an indicator for the path
|
|
Draw.ingame.SolidCircle(path.vectorPath[currentWaypoint] + Vector3.up * .02f, Vector3.up, .3f);
|
|
Draw.ingame.Arrow(transform.position, transform.position + Direction.ToVector3(), Vector3.up, .3f);
|
|
}
|
|
}
|
|
|
|
} |