Dynamic Obstacle Avoidance

Hello!

I released new package on Asset Store. Its Dynamic Obstacle Avoidance package.
Its usefull for using on npc characters, movable objects without nav mesh carving and behaviour that need local avoidance.

Here is demo video:

… and here is link to demos so you can test how it works.
DEMO/S

Usage:
In this demos I made it so chracters can push objects if there is no other way of traversing through obstacle but you assign high repulsion value so characters will not go near. It all depends how you tweek certain object.
Also you can assign character more persistance value in path following so it will more likely to go through obstacles or asssign lower persistance to make them less likely to go through.

You can get it at: AssetStorePage

Thank you !

1 Like

WOW nice asset!
How easy is it to add the obstacle avoidance to mercenaries/fallowers or enemy that is already in an RPG project???

Hello,
On objects all it takes is to put ‘Obstacle’ component on it

On npcs, you have to implement IAvoider interface and
add:
’ ObstacleManager.CalculateObstacleAvoidance(ref move, this);’
after all movement ( after path is calculated, being it NavMesh or other )

There is also an option to smooth npc avoidance if you like.
For that you can copy code from examples which is between SMOOTH_MOVEMENT macro.
Look at the _add_local_avoidance() method, its the main one.

Note that in some npc scripts I set movement y to zero because npcs are walking on ground and physics is responsible for Y axis movement ( jumping, falling )
But you dont have to do that if npc if flying.

I definitely need this for all my fallowers/mercenaries and enemies, hope this helps make them smarter…
Thank You…

And did it help?

Can anyone tell how well it works with ai agents controlled by mecanim?

I’m making my mecanim agents move via:

ai.navAgent.speed = (_animator.deltaPosition / Time.deltaTime).magnitude;

Does it make any difference how the NavMeshAgent is controlled or do I need to rewrite some code?

Not sure yet, still have one more question to ask the developer.

Hi, I have one more question if you don’t mind. Will this support automatic integration with an existing movement system script that is already being used on an enemy???

Thank You again…

It doesn’t matter what movement calculations you are using as long as you put avoidance method/s last ( after movement)
It takes existing movement vector ( velocity ) and modify it to take avoidance into account.

Allright sir, I’m making my purchase today…

Please let us now how it goes. I just can’t get it to work with mecanim (without root motion).

This is how I handle the ai movement:

void OnAnimatorMove() {

     RotateTo(orientationDir);

     Vector3 localDesiredVelocity = transform.InverseTransformDirection(navAgent.steeringTarget - this.transform.position).normalized * movementSpeed;
 
     animator.SetBool("Move", (Arrived() == false));

     navAgent.speed = (animator.deltaPosition / Time.deltaTime).magnitude;

     animator.SetFloat("X", localDesiredVelocity.x);
     animator.SetFloat("Z", localDesiredVelocity.z);
}

What would be the best way to integrate the avoidance velocity? Sorry I just can’t get my head around this.

Hi,
Ok, try this:
get world move direction which is:
Vector3 direction= (navAgent.steeringTarget - this.transform.position).normalized.
After that add ObstacleManager.CalculateObstacleAvoidynce( ref direction, this);
Then you’ll get modified direction for avoidance.
And than you can continue like you do:

Vector3 localDesiredVelocity = transform.InverseTransformDirection(direction).normalized * movementSpeed;

animator.SetBool(“Move”, (Arrived() == false));

navAgent.speed = (animator.deltaPosition / Time.deltaTime).magnitude;

animator.SetFloat(“X”, localDesiredVelocity.x);
animator.SetFloat(“Z”, localDesiredVelocity.z);

Thanks, this helps. Now the actors are at least playing the correct directional move animations, however they still move along the path without avoidance. I think it’s because the avoidance velocity isn’t added to the actual navmeshAgent velocity which moves the ai? I’ve looked through the example scripts but couldn’t find anything helpful for my case. Can you tell me what I need to add?

In the start or awake method set navAgent.updatePosition = false;
now calculate path manualy:
create this method:

NavMeshPath path;
        protected bool calculate_path(NavMeshAgent navAgent, Vector3 destination, ref Vector3 moveDirection)
        {
            if (path == null) path = new NavMeshPath();

            Vector3 transformPosition = transform.position;
            if (!navAgent.CalculatePath(destination, path))
                return false;

            if (path.status != UnityEngine.AI.NavMeshPathStatus.PathComplete)
                return false;

            if (path.corners.Length < 2)
                return false;


            Vector3 currentWaypoint = path.corners[1];
            Vector3 toTarget = currentWaypoint - transformPosition;
            moveDirection += toTarget.normalized;

            return true;
        }

now change code with this:
Vector3 movement = Vector3.zero;
calculate_path(navAgent, DESTINATION_VECTOR, ref movement); // calculating nav mesh path
ObstacleManager.CalculateObstacleAvoidance(ref movement, this); // adding avoidance

rest like it was:

Vector3 localDesiredVelocity = transform.InverseTransformDirection(movement).normalized * movementSpeed;

animator.SetBool(“Move”, (Arrived() == false));

navAgent.speed = (animator.deltaPosition / Time.deltaTime).magnitude;

animator.SetFloat(“X”, localDesiredVelocity.x);
animator.SetFloat(“Z”, localDesiredVelocity.z);

Thank you for your help! I did what you posted but can’t get it to work. Now the navagent moves but the animator avatar won’t follow, it’s keeping its initial position doing animations and turning like it’s supposed to but not changing position.

I’ll study the example scripts some more, maybe i’m overlooking a simple thing.

Oh yes, your character was moved by nav agent.
Lets try implement root motion controlled by script in OnAnimatorMove method
Add this code in OnAnimatorMove():

if (Time.deltaTime > 0 )
            {
                Vector3 v = (m_Animator.deltaPosition * moveSpeedMultiplier ) / Time.deltaTime;
           
 // IF USING RIGIDBODY
                if (m_Rigidbody)
                {
                    if (m_Rigidbody.isKinematic)
                        transform.position += v * Time.deltaTime;
                    else
                    {
                        if (m_Rigidbody.useGravity) v.y = m_Rigidbody.velocity.y;
                        m_Rigidbody.velocity = v;
                    }
                }
                // ELSE
                else
                {
                    transform.position += v * Time.deltaTime;
                }
            }

Just make sure that Root Transform Position ( XZ )is not baked into pose.

Im my script ‘CharacterObstacleAvoidanceAgent’ you can see how I implemented NavMeshAgent and obstacle avoidance.
Disabling NavMeshAgent update, calculating path manualy ( like here ) and moving character by root motion by script.
Look in ‘CharacterObstacleAvoidanceAgent.cs’ and ‘ThirdPersonCharacter.cs’

Thank you very much for your time. The thing is that I try to avoid rootmotion because the movement is too unprecise for my project.
That’s why I decided to go with something like:

navAgent.speed = (animator.deltaPosition / Time.deltaTime).magnitude

Sorry I should have mentioned this before.

But with all you posted I can make DOA easily work in my other non-mecanim projects. Thanks for your help and this great asset!

i also dont use root motion, just the navmeshagent using the animator deltaposition like is show in the previous post. I dont have clear if it works with this solution.

To use on NavMeshAgent you have to find the way to modify agent’s position to include avoidance direction.
I did it by using NavMeshAgent.nextPosition.

I’ll update the package with example of it.

Was looking at this package and it looks great, do i need to use navmesh with this, or can they handle basic tracking and avoidance without it?

No nav mesh not required.
Examples are using nav meshes but I can be used without it.
Core obstacle avoidance do not take nav mesh into calculations.