Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

844
Views
Unity - How to jump using a NavMeshAgent and click to move logic

I am building a game where the player can be controlled using the mouse input, using a click to move logic via a navmesh agent.

In order to let the player jump, I started using a CharacterController as well which should help managing the player. My issue is that I can't figure out where to put the jump logic. All references I found are related using the character controller without the navmesh agent.

I can get rid of the CharacterController if needed, but the NavMeshAgent has to stay.

Here it is a working code which allows to walk. Can you please help me with the jumping logic?

  private NavMeshAgent _agent;
  private CharacterController _characterController;
  private Vector3 _desVelocity;

  private void Update()
  {
     if (Input.GetMouseButtonDown(0))
     {
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo))
         {
             _agent.destination = hitInfo.point;
         }
     }
     var currMovementDirection = _desVelocity.normalized * currentSpeed;
     if (_agent.remainingDistance > _agent.stoppingDistance)
     {
         _desVelocity = _agent.desiredVelocity;
         _characterController.Move(currMovementDirection * Time.deltaTime);
     }
 }
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can achieve this using a Rigidbody instead of a CharacterController. The trick is that you need to disable the NavMeshAgent in order to jump.

Optionally, you set the destination to where you are at the time of the jump, so that the agent doesn't continue the simulation while the jump is happening.

Using collision detection, you turn the NavMeshAgent back on again once you land.

public class PlayerMovement : MonoBehaviour
{

    private Camera cam;
    private NavMeshAgent agent;
    private Rigidbody rigidbody;
    public bool grounded = true;

    void Start()
    {
        cam = Camera.main;
        agent = GetComponent<NavMeshAgent>();
        rigidbody = GetComponent<Rigidbody>();
    }

    void Update()
    {
        // clicking on the nav mesh, sets the destination of the agent and off he goes
        if (Input.GetMouseButtonDown(0) && (!agent.isStopped))
        {
            Ray ray = cam.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                agent.SetDestination(hit.point);
            }
        }

        // when you want to jump
        if (Input.GetKeyDown(KeyCode.Space) && grounded)
        {
            grounded = false;
            if (agent.enabled)
            {
                // set the agents target to where you are before the jump
                // this stops her before she jumps. Alternatively, you could
                // cache this value, and set it again once the jump is complete
                // to continue the original move
                agent.SetDestination(transform.position);
                // disable the agent
                agent.updatePosition = false;
                agent.updateRotation = false;
                agent.isStopped = true;
            }
            // make the jump
            rigidbody.isKinematic = false;
            rigidbody.useGravity = true;
            rigidbody.AddRelativeForce(new Vector3(0, 5f, 0), ForceMode.Impulse);
        }
    }

    /// <summary>
    /// Check for collision back to the ground, and re-enable the NavMeshAgent
    /// </summary>
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider != null && collision.collider.tag == "Ground")
        {
            if (!grounded)
            {
                if (agent.enabled)
                {
                    agent.updatePosition = true;
                    agent.updateRotation = true;
                    agent.isStopped = false;
                }
                rigidbody.isKinematic = true;
                rigidbody.useGravity = false;
                grounded = true;
            }
        }
    }
}
over 4 years ago · Santiago Trujillo Report

0

The jump logic should be inside the Update() method since we want the height to be calculated every frame.

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo))
        {
            _agent.destination = hitInfo.point;
        }
    }
    var currMovementDirection = _desVelocity.normalized * currentSpeed;

    groundedPlayer = _characterController.isGrounded;
    if (groundedPlayer && currMovementDirection.y < 0)
    {
        currMovementDirection.y = 0f;
    }



    // Changes the height position of the player..
    if (Input.GetButtonDown("Jump") && groundedPlayer)
    {
        currMovementDirection.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
    }

    currMovementDirection.y += gravityValue * Time.deltaTime;
    if (_agent.remainingDistance > _agent.stoppingDistance)
    {
        _desVelocity = _agent.desiredVelocity;
        _characterController.Move(currMovementDirection * Time.deltaTime);
    }
}

Please see the official docs here

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!