Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Help with manual NavAgent movement and understanding it's public properties

Discussion in 'Navigation' started by Eudaimonium, Oct 2, 2018.

  1. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Hello,

    I have spend the last couple of hours digging through the following documentation:
    https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.SetDestination.html
    https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent-desiredVelocity.html
    https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent-nextPosition.html

    After following through all materials present in the manual, I thought I was good to go.

    I have an enemy driven by a custom state-machine behavior AI. It decides when to use root motion, how to attack, when to approach or back off from the player etc etc. So naturally I though I could just use NavMesh Agent to query it's pathfinding and take it from there.

    Boy, was I wrong. But let's start at the beginning.

    Logically, I thought the following steps would suffice:
    - Turn off updatePosition and updateRotation to prevent my AI Agent taking control of my enemy's position and rotation. This... is really unnecessary, why not have a seperate "automatic navmesh movement" script for that? All I need is a path.
    - Set the Agent's destination property or use SetDestination method... both of which apparently do the same thing since you can query pendingPath? Whatever, that bit works.
    - Ask the agent where should I move this frame. This is where it all fell apart.

    So apparently, nextPosition is not where I want to go on the next frame.

    Reading and drawing a debug line for a "nextPosition" property without setting it myself to anything at all just draws a straight line from the enemy to my player. This led me to a completely wrong debugging path.

    I thought, "OK there's the desired velocity thing! That's where I need to go!". Well... almost.

    So I finally found out:
    If I do SetDestination to player's position every frame, but do not touch nextDestination property, reading and moving towards desiredVelocity every frame... lets me control the enemy! It mimics my player's movements in world space.

    Drawing a Debug line towards desired velocity basically confirms it - desired velocity follows my player's movement velocity.

    So, at this point I'm losing it... how can it go so wrong? How do I fix it?

    Easily. For future google travelers, if your enemy mimics the movement direction of your pathfinding target, do this:
    Code (CSharp):
    1. Enemy.Agent.nextPosition = Enemy.transform.position;
    ...where Enemy is your GameObject and Agent is the "NavMeshAgent" component on it. Then, simply move your enemy towards desiredVelocity.

    This somehow fixed the pathfinding. Yay!

    So, in the conclusion... what on earth? The navmesh creation workflow is great... the carving zones, manual link creation, automatic link creation, jump gaps, surface costs, surface types... And then this API thing is... not meant to be used in production, apparently.

    All I wanted to was to give a navmesh agent a destination, and ask "OK chief, where do we move this frame?"... I ended up setting the agent's "nextPosition" to it's own worldspace position to avoid my player mind-controlling it's movements.

    Am I something obvious? Is there a step I missed in the setup of all this? Are there bits of documentation I somehow missed?

    Man I cannot wait to start handling the offmesh link traversals...
     
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    I'm with you, the NavMeshAgent is frustrating to control. It really is built to simply be set and let go, and worst of all you cannot derive from it to easily roll your own.
    It's a terrible shame, if they'd made the NavMeshAgent a lot simpler (I'm thinking setting and getting a path, have properties like speed and turning radius etc, and allowing you to call a Move() which by default moves it further one frame on the path and perhaps be overloaded with Move (Vector3 pos) in case you want to divert) and make it much easier to write your own custom solution on top of that it'd be great.
    Right now rolling your own agent means having to rewrite parts like ensuring your position stays on the NavMesh at all times, which I'm pretty sure Unity can do in a lot more performant way than we ever could.
     
    kadir_yuksel likes this.
  3. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    This. Quite a few Unity features seem to be built only for the purpose of completing the video tutorial on the topic, but not much else.

    Also... the manual downloading of zip file and extracting assets just to access the complete set of Navigation features? Why include half of the functionality in the engine, and half on some .zip download?

    Why not put it on the Asset store or Package manager at least?
     
    kadir_yuksel likes this.
  4. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    I suppose it's great for prototyping, when you don't want to fiddle with component configurations.
    As for the components, as I understand it those were added later and are technically still experimental, hence why they're not on the store, although the Package Manager would be a great place for them now, since betas and such go there. They might simply have forgotten or are currently prioritizing the ECS interfacing.
     
  5. ShadyMike

    ShadyMike

    Joined:
    Apr 14, 2013
    Posts:
    60
    Thank you, this saved me a lot of time today!