Hello,
i am currently diving into the new pathfinding thingies. While i had success with enemies following a character and YES stopping in some distance, i wonder how to setup these things:
Of course you have a user driven character. Mine is currently physics driven. So it does not benefit from the navmesh. I mean, he just can go through any Not walkable area. What is the recommended way to solve this. Just add a navmeshagent to him? Or remove the rigidbody and the physics scripting and control the velocity of the agent? But you still need a collider to catch bullets and so , right? Or use a character controller? If so, why? The Demofiles did not show anything like that.
The Navmesh agent Component seems to be good for Human or animal characters. because of the turning behavior. Everything that turns immediately or on one spot like a Tank can be done somewhat convincingly. But how about a car or a boat? Those can only go forward and cannot spin on a point.
Obstacles. As far as i could figure this out, for an obstacle you simply add Navmesh Agent to the gameobject. But how do you control which object can push away which other object? My results are rather pushypushy. And jittery.
the navmesh works great for static scenes without lots of collidable moving geometry… if your scene changes, you’d have to update the navmesh and re-calculate your paths.
I made a boat game using this system, the boats use physics, I separated the boat from the agent. I made the agent pathfind, then I made the boat turn towards the agent and accelerate towards it when facing it.
e.g not facing agent → boat turns but doesnt accelerate
facing agent → boat accelerates.
Then in turn the agen has a script that ‘leads’ the boat. If moves faster and slower so that it never leaves the boat behind, based on range from the boat.
This setup works well.
…and boats can pretty much turn on the spot and look ok. (cars can’t though)
For the player character are you not wanting it to go on non-walkable areas? In that case you can just block them off with invisible colliders that only collide with the player layer.
For obstacles you can put kinematic rigidbodies on to the obstacle agents, but they can still cause funny jitter, stuck characters agents. Or if you know where obstacles are going to be( like for doors/bridges) you can bake those areas on different navmesh layers and toggle them on and off. This gets pretty hard if you have a lot of different layers however.
1:
I would definitely base your player controller off a NavMeshAgent and save yourself the time of duplicating the dataset of the NavMesh through colliders.
Set your rigidbody to kinematic and add a NavMeshAgent to the player GO. Then in stead of modifying the velocity of the rigidbody, modify that of the NavMeshAgent. The most solid way of doing that at the moment is through myAgent.Move (someVelocityVector);
If you want to handle the player walking into walls a bit more gracefully, use NavMesh.Raycast to shoot a ray forward in NavMesh space and figure out if the player is about to collide with something.
2:
You can try modifying the angularSpeed for the agent and see if that yields more desirable results, but if that is not enough control for you, you can always turn off complete NavMeshAgent control and in stead use it to guide a script doing the actual movement.
So one setup could be to set myAgent.updatePosition = myAgent.updateRotation = false; and then read out myAgent.desiredVelocity for use in a script controlling your car or whatever via a rigidbody or perhaps direct transform modification.
3:
One way of adding dynamic obstacles is indeed to attach a NavMeshAgent to them. To avoid the funky behaviour EddieC describes, you’ll need to turn off position and rotation updating on them as well.
There is presently no system for saying "this guy can push that guy, but not the other way around) though. Alternatively - if you just need semi-dynamic obstacles (such as doors), you could use off-mesh links or NavMeshLayers being enabled or disabled.
Ahhhh, thanks guys! The first two answers i thought about myself. Good to hear you made something this way and it worked out.
And another question converning answer 1 to the godfather of unity pathfinding:
Why do i need a rigidbody on a character with a Navmeshagent? You say script the velocity of the agent. Whats the rigidbody good for then? Gravity?
if there were a rigidbody, what would happen if i use AddForce() to it? I assume nothing, since the NavMeshAgent overrides this, or?
Do i need another collider to catch bullets? I mean the navmesh Agent has some kind of a Capsule Collider, but i cannot access it. Thus it seems i need to have an extra one, or not?
Edit: More Questions
if enemys shall constantly follow a character, is it a good idea to set their target every in update? Or because of performace rather do that 1 half a sec or so?
are there other ressources on the topic then the older demofiles available under the betas downloadpage?
while i was searching for the topic i only found some youtube things where people made a basic follow me. And i found a lot of questions like, my agents don´t stop in a distance, they get pushed away and the like. I think there is the need to have more info on this, be it better documentation or examples or a blog entry or whatever.
So far i tried to learn from Angry Bots, so my setup of characters is similar to that. Maybe they could modify angry bots to work with Pathfinding instead Physics. That would be interesting to see. Quite a lot of work though.
Thanks a lot for explaining, AngryAnt.
A kinematic rigidbody serves to register a dynamic object with the PhysX runtime without actually receiving feedback from PhysX or affecting the transform of the GameObject it is attached to. You’ll need that to have the collider(s) on the character move properly and push other physical objects.
Remember that moving colliders without rigidbodies assigned (also known as static colliders) will result in the static collision geometry to be recalculated - meaning you end up with a completely unnecessary and massive physics overhead.
See above - setting a rigidbody to kinematic means it only serves to register and update a dynamic object in PhysX - it doesn’t actually affect its transform in any way.
Just keep the collider you’ve been using until now. The navmesh agent has no collider - it does not tie into PhysX in any way. What you’re seeing is the visualization of the agents size, which is only used in the navigation system.
The NavMeshAgent doesn’t do a complete recalculation of its path if the new destination is close to the old one - in stead it appends to it. However if you have a lot of agents doing that, it will of-course carry a cost.
I would suggest that you repath in a loop in a coroutine and in there, if myAgent.remainingDistance > kFarAway, yield return new WaitForSeconds (kABitOfTime); else yield return null;
The example projects from the 3.5 public beta page is what we have at the moment. More are on the way and we’re putting these demos on the asset store (meaning they will show up in the gallery section as well) as soon as possible.
Yea we’re shipping more demos soon, but I don’t fully understand which problems you’re referring to. Could you elaborate?
Initially we will be shipping new demos showing off how to use the NavMeshAgent for pathfinding as well as player movement, but it is indeed something I have considered. No promises yet though - my TODO list before that eventuality has quite a few items on it
Thanks a lot again, indeed this information is already very valuable.
“Yea we’re shipping more demos soon, but I don’t fully understand which problems you’re referring to. Could you elaborate?”
I can only say what was hard for me to understand, and what i found as questions.
For me it was not obvious that the acceleration parameter also is invoked in decelaration. Also, Stopping Distance implies that the agent would automatically stop without any further scripting. I found this not the case. Had to do it in script. Also setting the agent to Stop(); and then set its destination again seems to start him again, without having called Resume.
Figuring this out takes quite some time.
The other not so abvious things i asked already here and they were answered.
the rigidbody is set to kinematic to register the dynamic object.
and yes my navmesh agent is trying to avoid the dynamic cube, but if the cube is in the shortest path my navmesh agent just tosses the dynamic cube away.
is there anyway that i can force a path recalculation ?
Hello,
for the dynamic obstacles ,I have some problems.
for example , in a scene ,I have two dynamic gameobjects A and B, add the Navmesh Agent on both of them .
I set object A a destination by agent ,but when A is finding the target position ,it will walk through the object B, not bypass it …
are there any other operations to control A to bypass B ?
you are taking about collision avoidance, which is a different thing from navmesh following/pathing.
you have a few options…
if B isn’t moving… set its collision to be a part of the navmesh scene and re-calculate the navmesh temporarily.
if both A B are moving, then…
you could try having sphere collision on both, and let them bump and slide past each other… this may be enough for what you are trying to achieve… but they might also get stuck
or You could detect their collision, then add an intermediate destination for both obects… say, back a bit and to the left, then continue on with the original destination
you could just let them pass through each other
you could look into some fancy “collision avoidance” perhaps there is something on the asset store
Thx for your replies !
I know what you mean ,but from the above guys said ,there is indeed some way to let the object attached with the NavMeshAgent Component to avoid the dynamic obstacles while it is finding the tartget …
for example :
It seems that if the Object A attached with the NavMeshAgent component want to avoid the Object B(it is moving in the scene) while it is finding the target position.
just attach a NavMeshAgent to it…
I also did that ,attach the NavMeshAgent on the Objecet B,but the Object A just walk through the Object B, I got confused …
By the way ,If the Object B is static ,I just bake it into the NavMesh, the Object A can bypass it while finding the target.
Hope this is ok - it feels as though the two threads are connected, so having a link here may be of interest to others also. All thoughts and suggestions appreciated.