Search Unity

2D NavMesh PathFinding......

Discussion in '2D' started by Vinnie711, Nov 8, 2017.

Thread Status:
Not open for further replies.
  1. codxr

    codxr

    Joined:
    Jun 19, 2019
    Posts:
    11
    Thanks @vhman, helped me a lot.
    I managed to dynamically generate my grid and then updating it manually when I need to.
    Code (CSharp):
    1. public NavMeshSurface2d surface;
    2.  
    3. public void UpdateMesh() {
    4.      surface.UpdateNavMesh(surface.navMeshData);
    5. }
    What do you mean with an implementation for Collect Objects option?
     
  2. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @codxr

    The option in NavMeshSerface2 Editor section, it is mostly not implemented in proper way.
    upload_2021-1-29_12-39-26.png

    "child" is straight forward, "volume" is tricky, "all" need to scan all objects - very not efficient.

    So I'm waiting for nice and efficient solution to come.
     
  3. codxr

    codxr

    Joined:
    Jun 19, 2019
    Posts:
    11
    I just made a pull request with my own solution for supporting multiple grids.

    I encountered the same problem and found out that UpdateNavMesh() is only working when it got baked before via BuildNavMesh() or the NavMeshSurface2d component already has NavMeshData assigned by hitting the bake button.

    The following code works for me:
    Code (CSharp):
    1.  
    2. public void UpdateMesh() {
    3.      if (surface.navMeshData != null) {
    4.          surface.UpdateNavMesh(surface.navMeshData);
    5.      }
    6.      else {
    7.           surface.BuildNavMesh();
    8.      }
    9. }
    10.  
     
    DungDajHjep and vhman like this.
  4. codxr

    codxr

    Joined:
    Jun 19, 2019
    Posts:
    11
    Hi vhman,
    I encountered some problems with the navmesh-system.
    I know you only wrote a wrapper for the navmesh to make it work in 2D, but maybe you know how to tackle this problem.

    Screenshot 2021-02-11 214400.png
    In the picture, the enemy is chasing the player and while he's doing that, he somehow walks over the wall.
    (He's chasing the player via navmeshagent.SetDestination()

    Screenshot.png
    For smaller enemies, everything is working just fine.
    Every tilemap has a NavMeshModifier attached to it, with the correct area override.

    I tried increasing the obstacle avoidance, but it had no impact.
    Also, I basically changed all properties, but the bigger enemy always walked over the wall.
    The bigger enemy uses a polygon collider 2D, I thought maybe it's because of the collider, but even a BoxCollider2D didn't change anything.

    Maybe you have an idea.
    Thanks in advance!

    Thanks to your github repo I was able to improve my enemy AI drastically, very much appreciated!
     
  5. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @codxr

    You need to bake NavMesh for every Agent Size/Type
    I believe that is the issue you have.
    upload_2021-2-12_11-45-7.png

    I have multiple NavMesh'es on my scene, one for NPC to walk on the roads and not grass, second for medium creatures (also used by medium player) and the third one for large creatures.
     
  6. codxr

    codxr

    Joined:
    Jun 19, 2019
    Posts:
    11
    @vhman Ah I see, thx it's working now

    All I had to do was create a new agent type, adjust the radius property of that created agent type, create a new NavMeshSurface2d for that agent type and change the agent type inside the NavMeshAgent of my bigger enemies.
     
  7. codxr

    codxr

    Joined:
    Jun 19, 2019
    Posts:
    11
    @vhman

    The only problem left is the following: My player and all my enemies use the NavMeshAgent component.
    The reason for my player using a NavMeshAgent is in order for it to push other enemies around.
    Player and enemies have colliders attached to them and a Rigidbody2d set to Kinematic (kinematic is needed otherwise the physics and navmesh system would conflict).

    big slime.png

    The big enemy has a PolygonCollider2d attached to it, player and the slime have a BoxCollider2d attached.
    I want them to use their 2dCollider for collision and not their NavMeshAgent obstacle avoidance radius.
    For smaller enemies, it isn't recognizable, but when the smaller slime or the player runs against the big enemy, it's pretty much weird-looking.

    Slime.png

    Is there any way to achieve this?
    I know you only wrote a 2d wrapper and not the entire NavMeshSystem, but maybe you know how to solve this due to your experience.

    Thanks again!
     
  8. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @codxr

    The only option to tweak avoidance is NavMeshAgent.avoidancePriority. You can achieve scenario that everybody avoids big enemies.

    As for problem with shape, there is no solution, except writing your own agent. You can implement event Physics based agent. I never done it, so I have no clues what problems you can encounter. But I know that pathing can be done without Agents, Agents are basically corresponds for local avoidance only.
     
  9. jairreal

    jairreal

    Joined:
    Sep 7, 2020
    Posts:
    6
    Can you use NavMesh to set unidirectional paths? I had to implement my own A* and 2D grid using tilemaps where I could selectively set unidirectional paths between nodes/tiles in the grid (tile map), but it's very basic and not optimized for performance, so I'm looking for something that could already be customized for unidirectional paths. The A* projects in the asset stores don't allow for this unfortunately :/
     
  10. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @jairreal

    NavMeshPlus does not implement any pathfinding at all. NavMeshPlus intendent to produce source objects for Unity NavMeshSurface native components. As with NavMeshSurface, there is not much to override in pathfinding process.

    The idea of UNIDIRECTIONAL pathing can be done by introducing INCLINE or STEP HEIGHT, agent can path it in one direction.
    upload_2021-2-14_11-26-35.png

    P.S. This is not the solution, but workaround.
     
  11. jairreal

    jairreal

    Joined:
    Sep 7, 2020
    Posts:
    6
    Thanks @vhman! I will take a look at that
     
  12. Lazy_Sloth

    Lazy_Sloth

    Joined:
    Apr 3, 2018
    Posts:
    39
    Hello vhman!

    I started to use your pathfinding solution and it works great, but I stuck with the rotation.
    As my project is a 2D top-down game, the agents should rotate along their way.
    But they don't do this, so they looks very dumb during movement...

    The 'updateRotation' and 'updateUpAxis' are set to false in the script.
    I tried to set true the first one, but -as you mentioned- it start rotate on the wrong axis.

    Can you help me how to fix this little issue or lead me to the right solution?
    The agents' rotation is necessary in a top-down game and should be a simple solution.

    (I don't use tiles only sprites with colliders + I clicked the 'Rotate Surface to XY' button)

    Please help me, thanks in advance!
     
  13. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Hello @Lazy_Sloth

    https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.html is a standard component. Look for public properties.
    I just tried to achieve rotation around Z and found that..

    In "normal" condition you walking on a XZ floor and rotate around Y. So, if 'updateUpAxis' false - your have wrong rotation.
    If you walking on a wall XY and 'updateUpAxis' is true - your rotation will be on Z, but now sprite will have -90 Y.

    So in either cases it will not work. And I don't recommend set sprite as child object -90 Y.

    The solution is a script to sync Agent.velocity (?) with your Transform.Rotation
    Try to experiment with snippet I have found on internet. It doesn't work, as my sprite flips over on 180 turns, but good point to start.
    Code (CSharp):
    1.             var targetRotation = agent.desiredVelocity.normalized;
    2.             Quaternion rotation = targetRotation != Vector3.zero ? Quaternion.LookRotation(targetRotation) : transform.rotation;
    3.             transform.rotation = rotation * Quaternion.Euler(0,-90, 0);
     
  14. Lazy_Sloth

    Lazy_Sloth

    Joined:
    Apr 3, 2018
    Posts:
    39
    Thanks! To be honest, this looks a bit confusing to me, but it's probably a good way to start to find a solution. Especially the 'Quaternion.LookRotation()' sounds interesting. I don't know why I never used this method...

    Anyway, I could write two scripts which works perfectly and do exactly what I was looking for! If you intend to update your pathfinding solution one time, you're free to use my script if you want. Of course anyone who are in my shoes and looking for a way how to rotate/turn agent towards the waypoints of the path, can use the script.. but don't forget I designed to use it in top-down games!

    I can provide two scripts to manage this issue. The first rotates agent instantly towards the waypoints, the second one rotates it "smoothly", so this looks more realistic. Obviously don't use both script simultaneously on the same agent! I left the 'OnDrawGizmos()' method in the scripts, so you can visualize the path/waypoints + agent's facing direction (transform.up).

    Everything works perfectly (tested), but using the smooth rotation script, when the agent turns in wide angle its rotation can look a bit ugly as the agent starts move immediately to the position meanwhile starts to turn. This looks like when someone suddenly turns back, but meanwhile doing this also move backwards at the same time... Not a big deal and can't really notice when agent's rotation speed high enough. My idea to fix this is to add some code which pause the agent's movement along the path (or decrease its speed) until the angle ('angleDifference') between agent's facing direction and the next waypoint direction is under the given value (45 should be fine). With this the rotation will be more realistic...

    Very easy to use the scripts! It goes without saying, but in the sake of noobs:
    1. Set-up the basic NavMeshPlus environment if it's not ready yet. (https://github.com/h8man/NavMeshPlus)
    2. Attach one of the scripts (download below) to the agents (don't forgot to add NavMeshAgent too..)
    3. Click on walkable area, so agents will go there meanwhile constantly rotate towards path's next waypoints

    Instant rotation:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3.  
    4. public class Rotate_Instantly : MonoBehaviour
    5. {
    6.     public bool showAhead;
    7.     public bool showPath;
    8.  
    9.     private NavMeshAgent agent;
    10.     private Vector3 nextWaypoint;
    11.  
    12.     void Start()
    13.     {
    14.         agent = GetComponent<NavMeshAgent>();
    15.         agent.updateRotation = false;
    16.         agent.updateUpAxis = false;
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         if (Input.GetMouseButtonUp(0))
    22.         {
    23.             Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    24.             RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
    25.  
    26.             if (hit.collider != null)
    27.             {
    28.                 agent.SetDestination(hit.point);
    29.  
    30.                 if (agent.path.corners.Length == 1)
    31.                 {
    32.                     nextWaypoint = agent.path.corners[0];
    33.                 }
    34.             }
    35.         }
    36.  
    37.         if (agent.hasPath)
    38.         {
    39.             if (nextWaypoint != agent.path.corners[1])
    40.             {
    41.                 RotateToPoint(agent.path.corners[1]);
    42.                 nextWaypoint = agent.path.corners[1];
    43.             }
    44.         }
    45.     }
    46.  
    47.     private void RotateToPoint(Vector3 targetPoint)
    48.     {
    49.         Vector3 targetVector = targetPoint - transform.position;
    50.         float angleDifference = Vector2.SignedAngle(transform.up, targetVector);
    51.         transform.rotation = Quaternion.Euler(0, 0, transform.localEulerAngles.z + angleDifference);
    52.     }
    53.  
    54.     void OnDrawGizmos()
    55.     {
    56.         if (Application.isPlaying)
    57.         {
    58.             if (showPath && agent.hasPath)
    59.             {
    60.                 for (int i = 0; i + 1 < agent.path.corners.Length; i++)
    61.                 {
    62.                     Gizmos.color = Color.white;
    63.                     Gizmos.DrawSphere(agent.path.corners[i + 1], 0.03f);
    64.                     Gizmos.color = Color.black;
    65.                     Gizmos.DrawLine(agent.path.corners[i], agent.path.corners[i + 1]);
    66.                 }
    67.             }
    68.  
    69.             if (showAhead)
    70.             {
    71.                 Gizmos.color = Color.red;
    72.                 Gizmos.DrawRay(transform.position, transform.up * 0.5f);
    73.             }
    74.         }
    75.     }
    76. }
    77.  
    Smooth rotation:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.AI;
    4.  
    5. public class Rotate_Smoothly : MonoBehaviour
    6. {
    7.     public bool showAhead;
    8.     public bool showPath;
    9.  
    10.     private NavMeshAgent agent;
    11.     private Vector2 nextWaypoint;
    12.     private float angleDifference;
    13.     private float targetAngle;
    14.     private float rotateSpeed;
    15.  
    16.     void Start()
    17.     {
    18.         agent = GetComponent<NavMeshAgent>();
    19.         agent.updateRotation = false;
    20.         agent.updateUpAxis = false;
    21.  
    22.         rotateSpeed = 80f;
    23.     }
    24.  
    25.     void Update()
    26.     {
    27.         if (Input.GetMouseButtonUp(0))
    28.         {
    29.             Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    30.             RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
    31.  
    32.             if (hit.collider != null)
    33.             {
    34.                 agent.SetDestination(hit.point);
    35.  
    36.                 if (agent.path.corners.Length > 1)
    37.                 {
    38.                     StartCoroutine("RotateToWaypoints");
    39.                     nextWaypoint = agent.path.corners[1];
    40.                 }
    41.             }
    42.         }
    43.  
    44.         if (agent.hasPath)
    45.         {
    46.             if (nextWaypoint != (Vector2)agent.path.corners[1])
    47.             {
    48.                 StartCoroutine("RotateToWaypoints");
    49.                 nextWaypoint = agent.path.corners[1];
    50.             }
    51.         }
    52.     }
    53.  
    54.     IEnumerator RotateToWaypoints()
    55.     {
    56.         Vector2 targetVector = agent.path.corners[1] - transform.position;
    57.         angleDifference = Vector2.SignedAngle(transform.up, targetVector);
    58.         targetAngle = transform.localEulerAngles.z + angleDifference;
    59.  
    60.         if (targetAngle >= 360) { targetAngle -= 360; }
    61.         else if (targetAngle < 0) { targetAngle += 360; }
    62.  
    63.         while (transform.localEulerAngles.z < targetAngle - 0.1f || transform.localEulerAngles.z > targetAngle + 0.1f)
    64.         {
    65.             transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, targetAngle), rotateSpeed * Time.deltaTime);
    66.             yield return null;
    67.         }
    68.     }
    69.  
    70.     void OnDrawGizmos()
    71.     {
    72.         if (Application.isPlaying)
    73.         {
    74.             if (showPath && agent.hasPath)
    75.             {
    76.                 for (int i = 0; i + 1 < agent.path.corners.Length; i++)
    77.                 {
    78.                     Gizmos.color = Color.white;
    79.                     Gizmos.DrawSphere(agent.path.corners[i + 1], 0.03f);
    80.                     Gizmos.color = Color.black;
    81.                     Gizmos.DrawLine(agent.path.corners[i], agent.path.corners[i + 1]);
    82.                 }
    83.             }
    84.  
    85.             if (showAhead)
    86.             {
    87.                 Gizmos.color = Color.red;
    88.                 Gizmos.DrawRay(transform.position, transform.up * 0.5f);
    89.             }
    90.         }
    91.     }
    92. }
    93.  
    Download scripts:
     

    Attached Files:

    Last edited: Mar 4, 2021
    unitydonauki123 and vhman like this.
  15. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Last edited: Mar 4, 2021
    Lazy_Sloth likes this.
  16. Lazy_Sloth

    Lazy_Sloth

    Joined:
    Apr 3, 2018
    Posts:
    39
  17. ditlevrisdahl

    ditlevrisdahl

    Joined:
    May 30, 2017
    Posts:
    26
    Hey @vhman

    Im loving your work!

    I'm building a TD game where i want to place walls as obstacles for enemies to walk around.

    What do i have to add to these gameobjects(walls) for them to be set as "not walkable" by the navmesh bake? It works when painting walls using tilemap, and setting tilemap to "not walkable". But this gameobject(wall) is not a tilemap. Am i missing something? :)
     
  18. ditlevrisdahl

    ditlevrisdahl

    Joined:
    May 30, 2017
    Posts:
    26
    Hello Again, i got it to work by moving my objects so they got grid as parent, and then added a sprite renderer. I found the anwser by reading through all other comments. Maybe put it into the tutorial :)
     
    vhman likes this.
  19. ditlevrisdahl

    ditlevrisdahl

    Joined:
    May 30, 2017
    Posts:
    26
    If anyone is interested in how to update navmesh during runtime I got the following to work for me:

    Code (CSharp):
    1. private NavMeshSurface2d navMeshSurfaces;
    2.  
    3. void Start(){
    4. navMeshSurfaces = FindObjectOfType<NavMeshSurface2d>();
    5.         navMeshSurfaces.BuildNavMesh();
    6. InvokeRepeating("doubleUpdateNavMesh", 0f, 1.0f);
    7. }
    8. void doubleUpdateNavMesh()
    9.     {
    10.         navMeshSurfaces.UpdateNavMesh(navMeshSurfaces.navMeshData);
    11.         navMeshSurfaces.UpdateNavMesh(navMeshSurfaces.navMeshData);
    12.     }
    13.  
     
  20. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    ditlevrisdahl likes this.
  21. Valynna

    Valynna

    Joined:
    Apr 1, 2021
    Posts:
    39
    Hey I've been trying to use your NavMeshPlus for a while now but I can't get it to work programmatically.

    I'm trying to do it all in code and not use GUI (for my procedural map generation), but whenever I run things, it finds all the required sources, but doesn't actually generate the NavMesh at all. Am i missing something? If I call "BuildNaveMesh", it should just bake the mesh, right? And it finds all the sources it needs to, so I don't get why it isn't producing a navmesh.
     
    Last edited: Apr 21, 2021
    ditlevrisdahl likes this.
  22. lofwyre

    lofwyre

    Joined:
    Apr 19, 2007
    Posts:
    174
    Hi vhman

    I had to do the same thing. It seemed to me like changing the navmesh in the current frame then calling UpdateNavMesh would update changes from previous frames but not the current, so I changed my code to do something like this;

    Code (CSharp):
    1. NavMesh2D.BuildNavMesh();
    2. StartCoroutine(NextFrameUpdateNavMesh());
    3.  
    4. public IEnumerator NextFrameUpdateNavMesh()
    5. {
    6.     yield return 0;
    7.     NavMesh2D.UpdateNavMesh(NavMesh2D.navMeshData);
    8. }
    9.  
     
    ditlevrisdahl likes this.
  23. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Hello @Valynna

    If you targeting sprites - it should work as intended RedHotSweetPepper/RuntimeBake.cs at master · h8man/RedHotSweetPepper (github.com)
    Check https://github.com/h8man/RedHotSweetPepper - SampleSceneRuntime.unity

    If you targeting colliders there is a lot of consideration. From wiki:

    Important note: NavMeshSurface2d should be a parent for all colliders if this option enabled. See NON-TILED below

    Important note: Collider's bounds not getting updated to match the transform until 'LateUpdate()' is called. Force the update by calling Physics2D.SyncTransforms() before calling 'BuildNavMesh()' programically.

    Important note: Physics updated only in fixed update, that is running in different time period. So its is not possible to generate physics in Awake/Start and call 'BuildNavMesh()' before 'LateUpdate()' to bake new geometry.

    Describe in details your scene setup, screenshots are welcome.
     
  24. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @lofwyre

    Interesting. Is it for tilemap, sprites or colliders?
     
  25. ditlevrisdahl

    ditlevrisdahl

    Joined:
    May 30, 2017
    Posts:
    26

    Hi again! Sorry for my late reply!
    I am actually not sure why i am calling build navmesh twice, but read through comments and saw others do it. I've tried removing it but then agents get stuck. So I'll just keep it as is. As it works flawlessly. Again TY so much for open sourcing this!!
     
  26. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Got it. I will put it in a backlog
     
  27. christh

    christh

    Joined:
    Jun 9, 2019
    Posts:
    10
    This package is great - thanks so much, @vhman . I added it to my project yesterday after a long day at work and had my enemies chasing me around my dungeon within 30 mins.

    Great work.
     
    vhman likes this.
  28. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Hi @vhman I have a question. How do I make it to fit more tight space?
    Darker blue area is the collison
     

    Attached Files:

    • ai.PNG
      ai.PNG
      File size:
      39.1 KB
      Views:
      299
  29. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @Shiina011

    To fit Agent into smaller space - just reduce agent radius and bake again.
    upload_2021-6-3_18-18-55.png
     
  30. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Thanks @vhman ! It works perfectly.
    Oh btw I got this error warning:
    Failed to create agent because there is no valid NavMesh

    Is it because I'm using this navmesh incorrectly? I still could move my agent using SetDestination even with the warning.
     
  31. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @Shiina011

    Hard to say what is going wrong. It can be that agent doesn't touches navmesh during loading.
    I also see this message from time to time. By the way, NavMesh produced are "native" to unity, so you can just search in other threads for troubleshooting.
     
  32. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Alright thanks, I'll leave it be because it doesn't seem to broke my project
     
  33. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Hey @vhman sorry I'm asking you here, I'm already asking other people and I couldn't found the answer.

    I have 3 pre-baked NavMeshSurface prefab.

    What I want to do is manually choose what NavMeshSurface the AI could move based on the 3 that I have baked by code.

    Is something like this is possible?
     
  34. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    @Shiina011

    Based on what you want achieve there is more than one possible scenario.
    1. Add all 3 navmeshes to the scene and enable only one of them.
    2. Bake 3 navmeshes for 3 agent types and switch agents agent type from code.

    Feel free to ask other questions.
     
    Shiina011 likes this.
  35. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    I'm trying the second one and it works fine. Thank you!
     
    vhman likes this.
  36. fodel

    fodel

    Joined:
    May 5, 2021
    Posts:
    4
    Last edited: Jun 14, 2021
  37. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Hello @vhman
    How do we rotate the AI along the path? I give the details of what I want to achieve on the image.

    Blue rect is a collision, red dot is the starting position, and green dot position is the goal. Black line is the path.

    I want the AI to use a correct direction sprite along that path.

    Example:
    When start moving the AI sprite facing left, on the next corner the AI facing up.
    I already have the sprite, I just don't know how to use it.

    Sorry I'm lack experience in these subject
     

    Attached Files:

  38. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Hello @Shiina011

    So you want use sprites for rotation, but not gameobject?
    It is a common approach. First you need lock agent rotation by these lines of code

    Code (CSharp):
    1. void Start()    {
    2.        var agent = GetComponent<NavMeshAgent>();
    3.        agent.updateRotation = false;
    4.        agent.updateUpAxis = false;
    5.    }
    After that use this video

    You need to get agent rotation, or speed, to determine where you are going to switch animations
     
  39. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Hi @vhman ! Thanks for your reply.
    I'm already done with my animator and tested everything, I have no problem.

    However my problem is when the AI already moving, I don't know how to rotate it, what I mean by that I don't know how the AI got the direction they should rotate into.
     
  40. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
  41. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    After some testing, in my case steeringTarget has the same value with agent.path.corners[0] which is the current agent position. I don't know why.

    So in the update, I'm checking if agent.path.corners.length > 1. Because the corners[1] contain the next point.
    And then I'm getting the direction by subtracting the corners[1] and current agent position.

    Right now my game looks good and the animation working perfectly. But I don't know if it may impact the performance in the future if I place more than 10 agents.

    Thanks for your help! Somehow that steeringTarget give me a "hint" which I don't know how lol.
     
  42. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    >>steeringTarget has the same value with agent.path.corners[0]

    Yes, if you will draw agent.path.corners as lines, you will see that agent updates its path along the path. From docs it should be agent.path.corners[+1]. But if it works, it fine.

    >>But I don't know if it may impact the performance in the future if I place more than 10 agents.

    You never know until it happens. You can test agent for 100 or 1000 units, but as game grows, scripts are heavier and heavier and it might drop FPS.
     
  43. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Alright, thanks I'll try it later.
    And one more thing, do you know how to disable the diagonal movement on the agent?

    I want the agent to only move in the horizontal and vertical direction
     
  44. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
  45. wiganda

    wiganda

    Joined:
    Feb 24, 2018
    Posts:
    14
    Having a great time using navmeshplus but came across an issue with gameobjects that use NavMeshObstacle (carve enabled).

    Right now I have 2 navmeshsurface2d and both get carved. What I want to do is decide which navemeshsurface2d gets carved.

    So after going through the NavMeshSurface2D.cs I see that 'm_IgnoreNavMeshObstacle' is set to true by default. No problem, I added it as a selectable option in NavMeshSurfaceEditor2D.cs so i can now select/deselect if a NavMeshSurface2D will ignore NavMeshObstacles.

    Issue now is though, that NavMeshSurface2D.cs checks if 'm_IgnoreNavMeshObstacle' is true AND if so it should do
    sources.RemoveAll((x) => (x.component != null && x.component.gameObject.GetComponent<NavMeshObstacle>() != null)); However, it never removes anything as component is always null, so it doesn't even get to check if the object has a NavMeshObstacle component, hence objects with NavMeshObstacle are always present in the 'sources' list which in turn will always carve them in every NavMeshSurface2D.

    So is there a way to check if an object in 'sources' has a NavMeshObstacle and then remove it from the 'sources' list so that it won't get carved.
     
  46. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    I'm looking into the issue, will update you later. But what I already have knowledge of is that NavMeshObstacle have bad design by not working with Layer system, so never used it to encounter the issue you have.

    The alternative is to update NavMesh on event or every frame, with cache of "sources".
     
  47. wiganda

    wiganda

    Joined:
    Feb 24, 2018
    Posts:
    14
    Thanks for the reply. Yes I can see, that even if I switch off detection(for example, a layer with car meshes) from one navmesh, unity still carves holes in that navmesh for the car meshes of the deselected layer (which is super weird).

    The other thing is that there is no way to actually prevent carving updates at all (other than of course switching off carving per mesh). Actually, that is the reason why there are no car meshes (I only put navmeshobstacle not navmesh modifier script on them) inside 'sources', hence why the 'm_IgnoreNavMeshObstacle' would currrently never work.

    So to confirm, there is no way to get access to unity's navMeshObstacle script or even make any script adjustments to change how navMeshObstacle works i assume?
     
  48. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
  49. ChrisMaster

    ChrisMaster

    Joined:
    Dec 27, 2013
    Posts:
    87
    Hello vhman, thank you for such a great packeg :)

    I have a question, I did follow intruction from pdf document from github. However I have a problem with baking navmesh if there were no navmeshmodifier on objects. Pdf stated if I read it corretly that it should bake by defualt walkable on it. What am I doing wrong? Or is the document outdated?

    Also is there any tool for creating offmeshlinks?

    Thanks in advance.
     

    Attached Files:

    • test.png
      test.png
      File size:
      134.7 KB
      Views:
      296
  50. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    360
    Sorry for late reply, pdf can be outdated, use wiki instead https://github.com/h8man/NavMeshPlus/wiki
    As I recall you need navmeshmodifier.

    Code (CSharp):
    1.  foreach (var modifier in root.GetComponentsInChildren<NavMeshModifier>())
     
Thread Status:
Not open for further replies.