Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

NavMesh registering hits even with collider in the way, but only within a certain range why?

Discussion in 'Navigation' started by neason080, Jun 21, 2015.

  1. neason080

    neason080

    Joined:
    Mar 30, 2015
    Posts:
    11
    Screenshot (16).jpg Screenshot (15).jpg Screenshot (14).jpg
    Ok scenario is I have a top downish kinda game with a small village. I want the inside of the buildings to be walkable. So what happens is when the player opens a door the roof objects are disabled, close the door they are enabled. To prevent the quirky behavior of the agent attempting to navigate inside with the door closed I tried various things. I made the door a nav mesh obstacle with carve enabled. That of course didn't work. So next I added a mesh collider to the roof. That's when things really got weird.

    After tinkering with it this is the result. If the click is registered at greater than 5.5 above the navmesh all is well the agent behaves as expected, meaning it does nothing. If on the other hand it's below that threshold 5.5 units on the Y axis or closer. The physics.raycast I'm using will freely acknowledge that I am hitting the roof object with the appropriate tag attached but for some reason the navmesh agent doesn't get the message and still tries to navigate to the point. Even coding it and calling the Stop function it ignores. I am either doing something horribly wrong or else this is a bug. If this is intended behavior for some reason or another a method to stop it would be appreciated.

    I have included screenshots to help visualize and maybe someone will notice a problem. Also the code I'm using for the same purpose. Please don't mind the bit of clutter I've been testing and debugging like crazy trying to get a solution or at least an explanation.

    using UnityEngine;
    using System.Collections;

    public class NavControl : MonoBehaviour
    {
    NavMeshAgent agent;
    // Use this for initialization
    void Start ()
    {
    agent = GetComponent<NavMeshAgent>();

    }

    // Update is called once per frame
    void Update ()
    {
    Move ();
    }
    void Move()
    {
    NavMeshPath navpath = new NavMeshPath();

    if (Input.GetMouseButtonDown (0))
    {
    Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    RaycastHit hit;

    if (Physics.Raycast(ray,out hit,100))

    {
    if(hit.collider.tag == "Roof")
    //if(navpath.status == NavMeshPathStatus.PathInvalid)
    {
    print(hit.point);
    print (" cant' get there");
    agent.Stop();
    }
    else if (hit.collider.tag == "Roof" && hit.collider.name == "Terrain")
    {
    agent.Stop ();
    }
    else
    print(hit.point);
    print (hit.collider.gameObject.name);
    agent.SetDestination (hit.point);
    agent.Resume ();
    }
    }
    }
    }
     
  2. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,649
    I think the solution you're looking for is OffMeshLink. Go back to the solution you had before of using the door to carve the interior and exterior of the building into separate NavMesh islands, and then add an OffMeshLink component to the door. By controlling the 'Activated' property of the OffMeshLink, you can enable/disable movement through the doorway, in line with whether the door is open or not.
     
  3. neason080

    neason080

    Joined:
    Mar 30, 2015
    Posts:
    11
    Afraid that is not the solution I'm looking for I'm sorry I'll be more clear. Entering and exiting the building is handled. The door is animated to open on click by rotating 90 degrees. This is in a nutshell the problem.

    If the door is closed or the OffMeshLink disabled and you click on the area inside the building the agent improperly determines there is a path and attempts to navigate it running into the walls and door, not very realistic behavior. I wish to either prevent a click on the interior of the room when the door is closed, or get the agent to realize thru code that the path is invalid.

    1. The mesh collider idea works except for the odd behavior mentioned above, that being when the Y distance between the click position and the navmesh is less than 5.5 the click on the collider is acknowledged. I can see it telling me roof object was clicked on, but it is then ignored and the agent attempts to navigate the path. This is particularly odd because the physics.raycast should have been blocked by the roof.

    2. Second it seems that the agent never realizes the path is partial or invalid until after another path is chosen. In another words it doesn't calculate the path and realize it's unreachable. It calculates and attempts to reach it as though a path exists. It's only if the user changes it's path that it returns the path invalid, and it always returns invalid. I have never seen the status return partial.

    Either of these two behaviors is what I am attempting to address. I did attempt the Off mesh link as proposed and as shown in the provided tutorial. Deactivate the link in the tutorial click on the empty box. The agent still attempts to navigate to the box no? That is the problem.
     
  4. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,649
    You don't want the agent to go to the door, open it, then walk through? That's what OffMeshLink would let you do...

    It's tough to see from your code - please use the [ code ] tags when posting code so that things like indentation can actually be preserved - but it looks like you're calling agent.SetDestination() regardless of what kind of collider the ray has hit. You don't have any braces after the 'else' clause so only the line that prints hit.point is actually guarded by it.
     
  5. neason080

    neason080

    Joined:
    Mar 30, 2015
    Posts:
    11
    Sorry for being unclear. Your right about the brace, blast, must have been tired, perhaps just brain dead we can poll that later.

    I want the agent to realize no path exists to get inside the room if the door is closed and stop or do nothing. Only if the door is open giving an open path should it try to move inside. Even with a navmesh link the agent attempts to go inside if the navmesh link is disabled. This causes the agent to endlessly bump into the walls or door.

    I actually found something similar but with four solid walls surrounding an inaccessible area. Same idea they don't want the agent endlessly attempting to access an area thats currently unreachable. They were using calculatepath and pathstatus to get the affect I'm looking for I think, I hope. Calculate the path if it returns partial or invalid do nothing. If valid set destination.

    I just realized I never calculated the path before asking for its status. That's what happens when only coffee is keeping your eyes open. Going to give that a go, and fix that brace.
     
  6. neason080

    neason080

    Joined:
    Mar 30, 2015
    Posts:
    11
    Yes NavMesh.CalculatePath as well as NavMeshPathStatus was indeed just the thing to get the behavior I was after. Well much closer. I'll need to tinker with it and build on the code for some situational behaviors stop at range to certain game objects with tag and what not but that really helped.

    Thank you guys at Unity for giving us this wonderful new system. It's really quite good without alteration and I'm finding the tools to customize it to be quite extensive thus far. Just have to not work on it for 14 hrs and be so tired as to blunder right over the answer. Thank you for your help as well superpig. Sorry about the lack of clarity in my post. Just means extra bacon for you.