AI path with navMeshAgent

Updated on June 21, 2018 in [A] Unity Scripting
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Reddit0
4 on June 20, 2018

Hey, i got a problem, i’m making some  AI minions that have to fillow a path (made by points) using nav mesh agent. So far my code is this one:

public Vector3 p1;
 public Vector3 p2;
 public Vector3 p3;
 private int destPoint = 0;
 private NavMeshAgent minionPath;
 private Vector3 nextpoint;
 public bool walking;
 void Awake()
 {
 minionPath = GetComponent<NavMeshAgent>();
 walking = false;
 }
 void Update()
 {
 minionPath = GetComponent<NavMeshAgent>();
 if (destPoint == 0)
 {
 nextpoint = p1;
 minionPath.SetDestination(p1);
 walking = true;
 }
 if (destPoint == 1)
 {
 nextpoint = p2;
 minionPath.destination = p2;
 }
 if (destPoint == 2)
 {
 nextpoint = p3;
 minionPath.destination = p3;
 }
if (Vector3.Distance(transform.position, nextpoint) <= 1)
 {
 destPoint += 1;
 return;
 }
 }

 

The code executes normally, the waliking bool is just there to make sure we see if it works or not (and it does). My problem is that the minion just won’t walk, (Btw, the “SetDestination” or the  “destination” are put diferent bc i was doing some tests to try fix this problem), is like the minion won’t recognize the vector3 p1, p2 or p3, just says walking = true but if i ask  with “minionPath.haspath” if it does have path, the answer is no, so, my uestion, is bc i seted it as vector 3 that it won’t recognie the point or i have something wrong?

  • Liked by
Reply
0 on June 20, 2018

What you should try doing is only change your destination once your withing some distance of your destination like you are doing on lines 33 – 36. What you have right now is your agent is constantly changing destination every frame to the next destination. So to sum it up you can just take all your if statements on lines17 – 32 and nest them in your distance check if statement.

  • Liked by
Reply
Cancel
0 on June 21, 2018

I think i understand, leme try, and thanks

  • Liked by
Reply
Cancel
0 on June 21, 2018

It just don’t work, If i put (instead of a Vector3) a transform.position of an emty object my minion works, but only if this minion is not a prefab. If it’s a prefab i need to put the emty object “point” as a prefab too, and when i call the spawn funcion it will spawn the minion normaly, but this one will not move

  • Liked by
Reply
Cancel
0 on June 21, 2018

Okay, so for the ones that have the same problems i camed with a solutions that is working just fine, what i did is adapt my minions ai with the one brackeys used for the tower defense turorials. Basically what i did was use the waypoints of his system and implemented on my minions movment script with the nav mesh agent:

What you have to do is, as he explained on the video (https://www.youtube.com/watch?v=aFxucZQ_5E4&t=1342s), create a waypont prefab with an emty object and put all your waypoints (in the path order) inside an emty object. Then u have to add a script to emty object, parent of all the waypoints, that “says” it contayn the points:

public class Type1Waypoints : MonoBehaviour {
public static Transform[] points;
void Awake()
 {
 points = new Transform[transform.childCount];
 for (int i = 0; i < points.Length; i++)
 {
 points[i] = transform.GetChild(i);
 }
 }
}

 

In this case i used “points” as name of my list of waypoints, but u can call it whatever u want. Also, i names this script Type1Waypoints, because since i have diferent types of minions i want them to follow a diferent path. So in my minion Script i adapted it this way:

(PD: I have more than one emty object “container” of the points of diferent paths with the same duplicated script. Only diference is that one is called Type1Waypoints and the other Type2Waypoints. Also in the first one the list is called points and in the second one the list is called points2)

public class MinionMele : MonoBehaviour {
public int minionType;
private Transform target;
 private int destPoint = 0;
 public NavMeshAgent minionPath;
 public bool walking;
 void Start()
 {
 if(minionType == 1)
 target = Type1Waypoints.points[0];
if(minionType == 2)
 target = Type2Waypoints.points2[0];
 }
 void Update()
 {
 minionPath = GetComponent<NavMeshAgent>();
 minionPath.destination = target.position;
 if(Vector3.Distance(transform.position, target.position) <= 1)
 {
 GetNextWaypoint();
 }
}
void GetNextWaypoint()
 {
 destPoint++;
 if (minionType == 1)
 target = Type1Waypoints.points[destPoint];
if (minionType == 2)
 target = Type2Waypoints.points2[destPoint];
}
}

In this script i puted 2 things, the first, and the one related with this post, the movment, i have the navigation mesh agent following the path of waypoints, but i also aded some code to define the type of minion is the one that runs this script. (This is because i din’t want to create 2 diferent scripts for each type of minion) so in the minion prefab i manually put a 1 or a 2 in the “MinionType” int depending of the path the prefab has to follow. So when it spawns, it knows if it has to follow the path of Type1Waypoints.points o the Type2Waypoints.points2.

 

PD: Since they are diferent scripts i could had named the 2 path “points” but i wanted to be more visible so i named one “points” and the other “points2”. When i say “points”, i mean whatever u want, just that u can name it the same way.

 

Thx

  • Liked by
Reply
Cancel