Search Unity

navmesh obstacle why does navmesh agent always go to same side of building destination

Discussion in 'Navigation' started by digiman72, Nov 21, 2018.

  1. digiman72

    digiman72

    Joined:
    Oct 6, 2018
    Posts:
    31
    hello there, I am continuing my RTS style game mini project, everything is working fine, however, I noticed something about navmesh when using carve on navmesh obstacle, it seems the Agent always goes to the same side of my storage hut building to drop stuff off, why is that ?? no matter how I place the building it will go around it, now I know that its made to do that, but how do I go about letting the Agent know that it is the destination required and not to try and go around ?? withouth removing carve on the object ?

    here is what it looks like :

    sameSide1.JPG

    sameSide2.JPG

    is there a way to stop this ? thanks for any help!
     
  2. digiman72

    digiman72

    Joined:
    Oct 6, 2018
    Posts:
    31
    or maybe there is a way to adjust the transform hit point vector and set it on the side the players coming from ??, lol, I know there's a way somehow..?
     
  3. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Because you're carving in the position you set the destination to is unreachable, so it'll always circle around. Your second idea will put you on the right track, and here's how to do it:
    use NavMesh.Raycast to cast a ray from your destination towards the agent, and the resulting hit will contain the last position your agent can reach on the straight line between your agent and your destination.
    Note, it is important to go from destination to agent because then the first hit will always be the edge of your destination. If you would cast the ray in the other direction, then it could possibly return a different obstacle on that straight line (like a rock or another building).
     
    digiman72 likes this.
  4. digiman72

    digiman72

    Joined:
    Oct 6, 2018
    Posts:
    31
    ok so I managed to make it work somewhat with the nav raycast, but if i use (from target to my transform) the position is the player pos , and so he don't move, lol.. i tried the reverse, but like you said if it hits another object before it wont work, it works fine if there are no obstuctions .too bad nav raycast doesn't have similar options to physics raycast, like transform etc..

    the raycast seems to come from inside the building and go through everything right to me..??
    so whats the problem?? can i use Distance somehow

    i have a box collider and nav obstacle on the building set to carve. the nav obstacle is just slightly bigger in size than the collider. if hat helps, so apparently the ray shot from the building is not detecting itself, perhaps because the inside of the building, the normals are not accessible or ?
     
    Last edited: Nov 23, 2018
  5. digiman72

    digiman72

    Joined:
    Oct 6, 2018
    Posts:
    31
    so what i tried next seems to work, i check for the distance between the objects, if its below or equal to say 8, i fire a navray cast from player to target, and then setDestination on navmesh to new vector point, but i do it on update where you check for navpath pending:

    Code (CSharp):
    1.  
    2.  if (navMeshAgent.remainingDistance <= navMeshAgent.stoppingDistance)
    3.             {
    4.                 if (!navMeshAgent.hasPath || navMeshAgent.velocity.sqrMagnitude == 0f)
    5.                 {
    6.                     // Debug.Log("ARRIVED......." + navMeshAgent.destination);
    7.                     hasArrived = true;
    8.  
    9.                     if (hasArrived)
    10.                     {
    11.                  
    12.                             doJob(lastHit, cargoType);
    13.                             hasArrived = false;
    14.                  
    15.                     }
    16.                 }
    17.  
    18.             }
    19.             else
    20.             {
    21.          
    22.                     if (lastTag == "StorageHut")
    23.                     {
    24.                         target = GameObject.Find(lastHit).transform;
    25.                         var vec = Vector3.Distance(transform.position, target.position);
    26.                         Debug.Log(vec);
    27.                         if (vec <= 6)
    28.                         {
    29.                      
    30.                             blocked = NavMesh.Raycast(transform.position, target.position, out hit, NavMesh.AllAreas);
    31.                             Debug.DrawLine(transform.position, target.position, blocked ? Color.red : Color.green);
    32.                             Debug.Log("NAVHIT...: " + hit.position);
    33.                             if (blocked)
    34.                                 Debug.DrawRay(hit.position, Vector3.up, Color.red);
    35.                             navMeshAgent.SetDestination(hit.position);
    36.                             //set = true;
    37.                         }
    38.  
    39.                     }
    40.              
    41.          
    42.          
    43.             }
    44.  
    or i guess i could of just used navmesh.remainding distance instead of doing another calculation ?

    But if another object or character happens to be blocking it even from that close i suppose it would cause a problem...

    and i noticed some lag in the game it gets choppy :eek:, lag gets horrible...
     
    Last edited: Nov 23, 2018
  6. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Are you executing that code in update? because then you're re-checking every frame which will likely cause that lag (especially if you're using this for multiple characters). Even so, like you said other obstacles will mess this solution up again...
    I do see your models have doors, wouldn't it be more useful if your character would always walk to one of those? Because if so, you could simply put an empty child gameobject on the house for each door and store these in a list, then when a house is clicked for walking to, the house checks which door is closest to the agent and then gives that door's position as the destination for the agent to walk to. It's a bit of a workaround, but it would be more efficient and has the added bonus of some extra realism.
     
    digiman72 likes this.
  7. digiman72

    digiman72

    Joined:
    Oct 6, 2018
    Posts:
    31
    well I managed to reduce the lag by moving around the code, and nulling variables, although it works "OK"
    there should still be away to point a vector at the target, and move the "new" hit destination ahead along the z axis outside of the building...?
    @Yandalf , but my brain gets tired after a while, lol
     
  8. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Well the easiest other option I see is to "cheat" double-sided collision for your house walls by, instead of a single box/mesh collider for the entire house, you put a box collider along every wall with a very thin thickness. That way the raycast from destination to the agent would work.
     
  9. the_0dium

    the_0dium

    Joined:
    Nov 29, 2018
    Posts:
    15
    You are using navmesh obstacles for houses?
     
  10. FlurinJenal

    FlurinJenal

    Joined:
    Nov 18, 2018
    Posts:
    18
    Hi Yandalf,

    Thanks for the useful hint with NavMesh.Raycast! It works fine for me when the ray is sent by the player towards the target, but it gets interrupted by other objects as you mention. When sending the ray from the target towards the player, it doesn't track the hit point of its own obstacle layer. Did I miss something?

    Edit: I solved the problem differently now, not with Raycast but by slightly adjusting the target position towards the player so the NavMeshAgent can find the position which is closest to the player and doesn't seem to just take a random position around the target element. Post #4 here helped: https://forum.unity.com/threads/agent-not-moving-toward-carved-obstacles.636418/
     
    Last edited: May 25, 2021