Search Unity

Dynamic Obstacle Avoidance

Discussion in 'Assets and Asset Store' started by username_unity_of_my, Apr 25, 2017.

  1. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    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 !
     
    Firlefanz73 likes this.
  2. motatob

    motatob

    Joined:
    Nov 20, 2012
    Posts:
    11
    WOW nice asset!
    How easy is it to add the obstacle avoidance to mercenaries/fallowers or enemy that is already in an RPG project???
     
  3. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279

    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.
     
    Last edited: May 28, 2018
  4. motatob

    motatob

    Joined:
    Nov 20, 2012
    Posts:
    11
    I definitely need this for all my fallowers/mercenaries and enemies, hope this helps make them smarter..
    Thank You..
     
  5. betaFlux

    betaFlux

    Joined:
    Jan 7, 2013
    Posts:
    57
    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:

    Code (CSharp):
    1. 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?
     
    Last edited: May 30, 2018
  6. motatob

    motatob

    Joined:
    Nov 20, 2012
    Posts:
    11
    Not sure yet, still have one more question to ask the developer.
     
  7. motatob

    motatob

    Joined:
    Nov 20, 2012
    Posts:
    11
    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..
     
  8. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    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.
     
  9. motatob

    motatob

    Joined:
    Nov 20, 2012
    Posts:
    11
    Allright sir, I'm making my purchase today..
     
  10. betaFlux

    betaFlux

    Joined:
    Jan 7, 2013
    Posts:
    57
    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:
    Code (CSharp):
    1.  
    2. void OnAnimatorMove() {
    3.  
    4.      RotateTo(orientationDir);
    5.  
    6.      Vector3 localDesiredVelocity = transform.InverseTransformDirection(navAgent.steeringTarget - this.transform.position).normalized * movementSpeed;
    7.  
    8.      animator.SetBool("Move", (Arrived() == false));
    9.  
    10.      navAgent.speed = (animator.deltaPosition / Time.deltaTime).magnitude;
    11.  
    12.      animator.SetFloat("X", localDesiredVelocity.x);
    13.      animator.SetFloat("Z", localDesiredVelocity.z);
    14. }
    What would be the best way to integrate the avoidance velocity? Sorry I just can't get my head around this.
     
    Last edited: Jun 4, 2018
  11. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279

    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);
     
  12. betaFlux

    betaFlux

    Joined:
    Jan 7, 2013
    Posts:
    57
    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?
     
  13. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279

    In the start or awake method set navAgent.updatePosition = false;
    now calculate path manualy:
    create this method:
    Code (CSharp):
    1.  
    2. NavMeshPath path;
    3.         protected bool calculate_path(NavMeshAgent navAgent, Vector3 destination, ref Vector3 moveDirection)
    4.         {
    5.             if (path == null) path = new NavMeshPath();
    6.  
    7.             Vector3 transformPosition = transform.position;
    8.             if (!navAgent.CalculatePath(destination, path))
    9.                 return false;
    10.  
    11.             if (path.status != UnityEngine.AI.NavMeshPathStatus.PathComplete)
    12.                 return false;
    13.  
    14.             if (path.corners.Length < 2)
    15.                 return false;
    16.  
    17.  
    18.             Vector3 currentWaypoint = path.corners[1];
    19.             Vector3 toTarget = currentWaypoint - transformPosition;
    20.             moveDirection += toTarget.normalized;
    21.  
    22.             return true;
    23.         }
    24.  
    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);
     
  14. betaFlux

    betaFlux

    Joined:
    Jan 7, 2013
    Posts:
    57
    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.
     
  15. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    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():
    Code (CSharp):
    1.      
    2. if (Time.deltaTime > 0 )
    3.             {
    4.                 Vector3 v = (m_Animator.deltaPosition * moveSpeedMultiplier ) / Time.deltaTime;
    5.            
    6.  // IF USING RIGIDBODY
    7.                 if (m_Rigidbody)
    8.                 {
    9.                     if (m_Rigidbody.isKinematic)
    10.                         transform.position += v * Time.deltaTime;
    11.                     else
    12.                     {
    13.                         if (m_Rigidbody.useGravity) v.y = m_Rigidbody.velocity.y;
    14.                         m_Rigidbody.velocity = v;
    15.                     }
    16.                 }
    17.                 // ELSE
    18.                 else
    19.                 {
    20.                     transform.position += v * Time.deltaTime;
    21.                 }
    22.             }
    23.  
    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'
     
    Last edited: Jun 6, 2018
  16. betaFlux

    betaFlux

    Joined:
    Jan 7, 2013
    Posts:
    57
    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:
    Code (CSharp):
    1. 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!
     
  17. dienat

    dienat

    Joined:
    May 27, 2016
    Posts:
    399
    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.
     
  18. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    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.
     
  19. joferjoe

    joferjoe

    Joined:
    Feb 2, 2016
    Posts:
    95
    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?
     
  20. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    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.
     
  21. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,116
    Hello,

    I am working on a 3d rpg, which has a landscape just made of chunks and each chunks contains blocks (like Minecraft... but with 45° slopes).
    Each chunk has one collider and one mesh where many blocks are "melted" together.

    So I cannot add a "Obstacle" script to each block, but I could add it to each chunk? Would this be possible or is it to slow then and not detecting ground anymore etc?

    Or can it just works using raycasts and "all in one" chunk colliders?

    Thanks a lot! This Looks very interesting :)
     
  22. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    Obstacle does not need to have collider attached.
    It can detect object by point ( position of object ), sphere ( position + radius ) or line ( two points ) and it calculates avoidance by those values.
    You can add Obstacle to all blocks or you can add on runtime when needed to object which needs it.
    Just remember to add newly created obstacle to ObstacleManager.obstacles list
     
  23. joferjoe

    joferjoe

    Joined:
    Feb 2, 2016
    Posts:
    95
    excellent thanks, is this usable for voxel terrains and navigating around walls and under caves (if they can see) or is this too much for this system?
     
  24. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    Hmmm, It can avoid convex shapes. This is not a pathfinding system.Its meant to work along with or without pathfinding systems.
     
  25. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    Hello,

    I released an update in which I added an example on how to use avoidance with Unity's nav mesh agent.

    Thx.
     
  26. bingofly

    bingofly

    Joined:
    Sep 15, 2018
    Posts:
    24
    Just bought it. I Test it by myself, the NPC is jitter and rotating like a fool, I can't find the reason.
     
  27. username_unity_of_my

    username_unity_of_my

    Joined:
    Feb 24, 2015
    Posts:
    279
    Can you be more precise?
    Is it problem with any demo scene?
    What type of character is causing you problems - one with nav mesh agent or one without ?
    Is creating new bot is causing problems?
    Does it show any errors?
    ...
     
unityunity