- Home /
Nav Mesh Agent don't let me jump
I'm working on a FPS, I've got a cube enemy. It has a Nav Mesh Agent component attached to. When active it don't let me use rigidbody.AddForce to make it jump. Here are the scripts:
To follow the player:
var target : Transform;
function Update ()
{
GetComponent(NavMeshAgent).destination = target.position;
}
And the second one, to make it jump when reach certain distance to player:
var target : Transform;//The player
var rayHit : RaycastHit;
var jumpDist : float;//distance the enemy will jump from
function Update () {
if(Physics.Linecast(transform.position,target.position,rayHit))
{
if(rayHit.distance < jumpDist)
{
print('Jump over player');
// animation.Play("jump");
rigidbody.AddForce(0, 20,0);
}
}
}
When I tested it, the console prints "Jump over player" and show no errors. But the enemy do not jump.
Why it's not working and how can I fix this?
Answer by arnezeehappyelf · Sep 27, 2012 at 06:37 PM
You got to stop or disable the navagent before you apply the force, otherwise it will stick to the navmesh.
Also, in your first snippet where you set the destination, it's faster (now it needs to look up and find the component every time you update), it also makes the code more readable if you just cache the component as you only need to use the getcomponent once in the Awake method. It's as simple as (in C# but more or less same in JS I suppose)
NavMeshAgent navAgent;
void Awake() {
navAgent = GetComponent<NavMeshAgent>();
}
Now your navAgent variable holds a reference to the component so you can just call navAgent.SetDestination() or whatever navmeshagent function you need.
So to fix the Jumping issue, just call navAgent.Stop() before you apply the force to the rigid body, calling navAgent.Stop(true) will stop the agent dead on (it uses the deaccelerate value otherwise) then call navAgent.Resume() whenever you land or hit something to start it up again.
Edit make sure that the rigid body is not kinematic and using gravity, you also need to add a force modifier so all the force is used at once. The below code works.
navAgent.Stop(true);
rigidbody.isKinematic = false;
rigidbody.useGravity = true;
rigidbody.AddForce(new Vector3(0,5,0),ForceMode.Impulse);
Edit 2 also use
rigidbody.AddRelativeForce(new Vector3(0,5,5),ForceMode.Impulse);
That way the force is always applied to the objects local forward.
This solution works well but I'm experiencing one side effect - the first (and only the first time) that I call Nav$$anonymous$$eshAgent.Stop( true ); will cause my AI to disappear. It will stay gone until Nav$$anonymous$$eshAgent.Resume() is called, at the end of the jump. However on subsequent calls to the same jump code it will not disappear.
Any thoughts, or observations gladly received :)
That's strange.. but observations are difficult if we can't see the code. Could you paste it over here?
Hi, Cinematronic, sure here is the relevant code, thanks in advance for your interest, are you also explicitly adding a RigidBody like I am?
//-----------------------------------------------------------------------------------
// This will cause the Crawler to disappear briefly the first time it is called, due
// to Nav$$anonymous$$eshAgent.Stop( true ) being called. TODO: Find out why this happens.
private IEnumerator Attacking()
{
// Stop or disable the navagent before you apply the force, otherwise it will
// stick to the navmesh.
_nav$$anonymous$$eshAgent.Stop( true );
BlendOutCurrentAnimation();
BlendInAnimation( AnimationType.Attack, 0.1f );
// Apply a force to make the Crawler jump
_rigidbody.is$$anonymous$$inematic = false;
_rigidbody.useGravity = true;
_rigidbody.AddForce( ComputeJumpForce(), Force$$anonymous$$ode.Impulse );
yield return new WaitForSeconds( JU$$anonymous$$P_DURATION * JU$$anonymous$$P_HIT_TEST_PLAYER_FACTOR );
if( PlayerIsCloseEnoughToHit() )
{
Hud$$anonymous$$anager.Instance.DisplayHitFlash();
// TODO: Spawn a 3rd person crawler?
_state = CrawlerState.FaceHuggingPlayer;
}
else
{
// We missed so fall to the floor
// A "bounce" animation that should be played once the crawler/jumper
// hits the floor (so it should look like they 'bounce' back into their standing position.
_state = CrawlerState.Bouncing;
}
yield return new WaitForSeconds( JU$$anonymous$$P_DURATION * (1f - JU$$anonymous$$P_HIT_TEST_PLAYER_FACTOR) );
// Turn the Nav$$anonymous$$eshAgent back on
_nav$$anonymous$$eshAgent.Resume();
// Turn the rigid body physics back to how they were before.
_rigidbody.is$$anonymous$$inematic = true;
_rigidbody.useGravity = false;
yield return null;
}
//-----------------------------------------------------------------------------------
private void Start()
{
_target = GameObject.FindGameObjectWithTag( "Player" );
SetupNav$$anonymous$$eshAgent();
SetupAnimations();
AddRigidBody();
}
//-----------------------------------------------------------------------------------
private void SetupNav$$anonymous$$eshAgent()
{
_nav$$anonymous$$eshAgent = GetComponent<Nav$$anonymous$$eshAgent>();
if (_nav$$anonymous$$eshAgent != null)
{
_nav$$anonymous$$eshAgent.enabled = false;
Debug.Log("Crawler: Nav$$anonymous$$eshAgent found");
}
else
{
Debug.LogError("Crawler: Nav$$anonymous$$eshAgent not found");
}
}
//-----------------------------------------------------------------------------------
private void AddRigidBody()
{
_rigidbody = gameObject.AddComponent( "Rigidbody" ) as Rigidbody;
if( _rigidbody != null )
{
_rigidbody.mass = $$anonymous$$ASS;
Debug.Log( "Crawler: Rigidbody added" );
}
else
{
Debug.LogError( "Crawler: Rigidbody not added" );
}
}
Cheers!
Thanks arnezeehappyelf. This was super helpful for myself, as I've been trying to use a navAgent to control the pathing for a sphere, which was to be moved by adding force. The navAgent's movement will just slide it around rather than rolling (I want it to roll).
I eventually got it to work by starting the NavAgent, passing it the desired destination, asking it which direction it would go next (navAgent.steeringTarget), then stopping the NavAgent and applying a force on the rigid body in that direction.
Seems to work a charm! Though I'd be interested to know if there was a more efficient method to use NavAgents with force...
Answer by Eclectus · Nov 21, 2012 at 04:11 PM
Update - I'd suggest setting the RigidBody.detectCollisions to false when the AI is not jumping, as it seems capable of interfering with the NavMeshAgent.
Your answer
![](https://koobas.hobune.stream/wayback/20220613081308im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
NavMesh does not working... 0 Answers
Navmesh carving and agent avoidence. 0 Answers
Reasons an NavMesh Agent.isStopped might be set to True? 0 Answers
Navmesh one way gate 0 Answers
Agents taking wrong path 0 Answers