How to make navmeshagent walk smarter

Hello,

I am making some kind of visualization in Unity.
The game is not playable by itself, the ‘player character’ will move on its own, and so will the NPC’s.
Thus I am using a navmesh and navmesh agents on both the ‘player’ character and all the NPC’s. I put the stopping distance for all my agents at 2.

Even though the walking to eachother is working good, there are a couple of annoying things going on.
What I want to happen is that when one walks to another, he has to stop in FRONT of the one he is walking to, and rotate in the direction facing him (so this is -180 on the Y of the one being walked to).

Currently this does not happen and I end up with various results, based on where the character was. It looks like this:

  1. This is the starting position : Imgur: The magic of the Internet the right one is the ‘player’, he is supposed to walk to the NPC (which is the one on the left)
    When the walking is done, he ends up like this : Imgur: The magic of the Internet . I agree this is still ‘quite’ acceptable, since it does like ok, even though he is a bit too much to the right.

  2. A much bigger problem occurs when the player is ‘behind’ the NPC. As can be seen in the starting position here: Imgur: The magic of the Internet
    When the walking is over here, the result is this: Imgur: The magic of the Internet . The player is standing behind the one he needs to walk to, and is not facing him at all as well.

How can I solve this (big ?) issue!

Thanks in advance,

Dennis

For #1, you can just make an empty GameObject as a child of your characters, and place it in front of the character. This is the point people should walk to. It will always be in front of them as they walk around. You will need some script to reference it on some type of CharacterScript, or you can Find it then move to it.

For #2, you can increase the angularSpeed of the NavMeshAgent component. They should turn faster, or you can run a function that turns him to face the direction after he has reached his destination.

Here are some example functions (C#):

    public IEnumerator MoveTo(Vector3 targetPosition, float distance)
    {
        // MOVE
        navMeshAgent.SetDestination(targetPosition);

        // ANIMATE
        animator.SetBool("IsWalking", true);

        // WAIT UNTIL DISTANCE IS CLOSE
        while (Vector3.Distance(character.transform.position, location.position) > distance)
        {
            yield return null;
        }

        // ANIMATE
        animator.SetBool("IsWalking", false);
    }

Call it like this: StartCoroutine(MoveTo(emptyGameObjectAtCharactersFeet.position, 0.2f));

Then after they arrive there, you have to turn them to face the character:

    public IEnumerator TurnToFaceSmoothly(Transform targetToLookAt)
    {
        // WHILE NOT LOOKING AT TARGET
        while (Vector3.Dot(transform.forward, (targetToLookAt.position - transform.position).normalized) < 0.95f)
        {
            // GET DIRECTION
            Vector3 dir = targetToLookAt.position - transform.position;

            // ROTATE SMOOTH
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 5f * Time.smoothDeltaTime);

            // ONLY ROTATE Y AXIS (CLAMP)
            transform.eulerAngles = new Vector3(0f, transform.eulerAngles.y, 0f);

            yield return null;
        }
    }

You are a god!! Thank you very much !!

@Stardog , the first idea with the empty child in front works perfect, thank you for that! Simple, yet effective!

For the turning problem, I am using this in a static method, so I found this script : http://benbeagley.com/2013/10/14/calling-a-static-ienumerator-in-unity/ which does I think what I need. I tried implementing it, but it keeps non-stop executing the turning function instead of just once?