Search Unity

NavMeshAgent with Character Controller gets disconnected

Discussion in 'Navigation' started by Hertzole, Jan 13, 2019.

  1. Hertzole

    Hertzole

    Joined:
    Jul 27, 2013
    Posts:
    422
    Hello

    I have some NavMeshAgents with a CharacterController attached (which I need for networking and other systems) and when the agents bump into each other, or some terrain, the CharacterController, or visual if you will, will get "disconnected". You can see it in the image below.



    All the agents are clumped together around a point, while their visuals are spread out and spazzing out while they are at it.

    This is the code I'm using to move the agents. (slightly modified for compactness)
    Code (CSharp):
    1. public class Agent : MonoBehaviour
    2. {
    3.     private NavMeshAgent agent;
    4.     private CharacterController controller;
    5.  
    6.     // Start is called before the first frame update
    7.     void Start()
    8.     {
    9.         agent = GetComponent<NavMeshAgent>();
    10.         controller = GetComponent<CharacterController>();
    11.         agent.updatePosition = false;
    12.         agent.updateRotation = false;
    13.     }
    14.  
    15.     private void Update()
    16.     {
    17.         controller.Move(agent.desiredVelocity.normalized * agent.speed * Time.deltaTime);
    18.         agent.velocity = controller.velocity;
    19.     }
    20. }
    I have a decent idea of why it happens. I suspect it's the desired velocity not really taking into account where it is and is just in what direction the agent wants to move. So if the controller gets disconnected, it will be out spazzing somewhere else.

    Here are some things I've tried already:
    I've tried to use nextPosition instead of desiredVelocity but that was even worse.
    I tried to turn off collision for the agents with each other, but that resulted in the picture above. With the collision on, they will stick together better when clumping together, but it's still certainly possible to break the connection.

    Anyone that has any tips on how to keep these two together?
     
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Why exactly are you using both a Controller and an Agent? If the Controller is also used for movement, the Agent is completely superfluous and is probably interfering.
     
  3. Hertzole

    Hertzole

    Joined:
    Jul 27, 2013
    Posts:
    422
    Currently, when using UNet (or something close to it), it's the best way to sync the movement. There's no way to sync a NavMeshAgent, and I don't know how to write a sync method for it, and just syncing the Transform results in really jittery movement.
     
  4. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Oh, that's super simple, actually! The reason why your motion is jittery is that the network only periodically updates the positions over the net (usually 10 times per second). You need to interpolate the position between updates to keep things smooth, and in the case of characters you could probably increase the update rate.
    Take a look at the networking tutorials and forums for this, they should help you out.
    Also, keep in mind that UNET is on the way out, and Unity hasn't made the replacement public yet. You might want to look at Mirror/HLAPI Community Edition, which is being talked about loftily at the moment: https://forum.unity.com/threads/mirror-networking-for-unity-unet-replacement.425437/
    They recently added transform syncs, with interpolation if I'm not mistaken.

    It doesn't make much sense to have a Controller and an Agent on the same gameobject. Controllers are meant to move a character via direct input, whereas a NavMeshAgent does that via pathfinding. These two are basically figthing for control, and since the source code isn't available for at least the Agent we actually can only guess how exactly this interaction is going wrong...
     
  5. Hertzole

    Hertzole

    Joined:
    Jul 27, 2013
    Posts:
    422
    I actually am using Mirror, but I said UNet because it's almost the same thing and more people are familiar with it. You're right in that they added a new NetworkTransform and it worked pretty good for the AI, but it didn't work at all for the rest of my moving items, so I had to revert it. But this one doesn't work well with just syncing transforms. No matter how I set the settings, it will be jittery. But now when I think about it, I could probably try and snag the new NetworkTransform and make it into a separate file.
     
  6. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Okay, how did it not work for the other moving items?
    Periodic updates of position are simply a limitation of networked games, it's simply impossible to send updates every frame without network usage going through the roof or simply giving out. Hence again, you'll have to interpolate.
     
  7. Hertzole

    Hertzole

    Joined:
    Jul 27, 2013
    Posts:
    422
    My players (actually using Character Controller) were quite jittery, rubber banding quite a bit and my grenades (using rigidbodies) wobbled in the air. The new NetworkTransform doesn't work well with physics/velocity related objects.
     
  8. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Yeah definitely don't combine network stuff with physics.
    People recommend to either only use network sync on startup and let the physics take care of the rest on each client after setting the initial velocities (such as with bullets or thrown objects), or to have the physics only be calculated on the server and sync up the resulting transforms with the clients. This is why the network managers in old UNet had prefab versions for clients and servers.