Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

2D NavMesh PathFinding......

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

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

    unity_XcvZUzrkJ7ji7Q

    Joined:
    Mar 17, 2019
    Posts:
    5
    Hey there. Thank you for this package. Its been a great help so far. But i still ran into a problem and am wondering if you might help me out with it.
    Im making a topdown game (zelda perspective) and generate some areas via code and bake the navmesh etc and everything is working nicely. i add placeable objects that carve themselves out of the navmesh and thats working nicely as well. now i was experimenting with agent radius for npcs and with voxelsize.
    lets assume i have a narrow corridor where there is one tile floor and to the left and right side a wall. when im using agent radius of 0.5 then the navmesh doesnt get generated. i made it a little smaller, and tried 0.49 (because maybe rounding problems or whatever) but the same. i ended up taking 0.33 and that seems to work quite good when i leave the voxel size at the standard 3x radius.
    now to the problem... when i make narrow corridors and have a corner leading into those (or maybe other corners as well but here is where i noticed it the most) then the agent will run to the side of the corner, moves towards the corner, sliding along the side and getting slower and slower and then when he is very close to the edge he stops and cant move away. ill add an example.
    i tried changing the voxelsize to a super slow 33x radius but its still the same. when i change the radius of the agent down to something like 0.1 then the problem disappears, but obviously the npcs start clipping through everything.
    they have a circle collider with 0.33 radius, the same as the setting in the obstacle avoidance but the collision is turned off. i changed the obstacle avoidance to none because otherwise the npcs would block each other indoors but its unchanged. i even get the feeling that when turning obstacle avoidance on the problem is better.
    this happens especially on corner but sometimes, when he gets a waypoint outside of the navmesh, he does the same on a straight wall.
    im kinda lost on how to fix this...

    here is a screenshot of the navmesh agents gizmos. the corner is made up of carved out objects, placed by me during runtime. i tried setting down the carving size a bit but that doesnt change anything.

    edit: i experimented around a bit more and it seems that the problem is mainly when having objects that carve out the navmesh close to another. e.g. i make a wall with chests that have a carve out value of x,y (1,1), so one tile sized and make a wall with them forming a corner. and its not on all corners as well. ive been trying different things and when i reduce the carve out size to 0.95, 0.95 then it works as well but im getting closer to the wall and the clipping starts again. gonna try this again after the long weekend. but if you got any idea what i should look at, that would be very helpful. thanks!
    upload_2021-7-10_15-7-21.png
     
    Last edited: Jul 10, 2021
  2. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @unity_XcvZUzrkJ7ji7Q,

    Hello. Thanks for describing the issue.

    I also encountered issues you described. Like agent radius 0.35 doesn't get mesh for corridors that are 0.75 units. So I just changed game design to accommodate that, as I'm not able to produce better solution than Unity's navigation system in given time constraint.

    But, I didn't encounter agent cornering issue, as I thought Unity's agent are very janky, so wrote my own with help of static member functions in NavMesh class (that also janky, but enough to move along the project).

    From image I see, on that corner you have 5 or 6 very narrow navmesh 'tiles' on 1 side, it can be the issue with the cornering. You can look up Unity's issues on pathing through to many tiles, I believe workaround is path splitting, but its only a guess.

    Also you can try to scale your game, so you will not get values bellow 1 in navmesh, it also can help.

    And finally, try out https://arongranberg.com/astar/features especially functions like:

    1) Grid Graphs
    2) 2D Pathfinding

    https://arongranberg.com/astar/freevspro it seems those features are free
     
  3. unity_XcvZUzrkJ7ji7Q

    unity_XcvZUzrkJ7ji7Q

    Joined:
    Mar 17, 2019
    Posts:
    5
    I have been playing around with this a little bit more and have been drawing corner points for the path to see how he is moving and he walks straight up to the edge and turns and continues. the amount of cells arent really the problem cos even with just 2 or 3 navmesh cells he slows down until basically standing.

    then i tried a different approach and was making a bezier curve out of the edges to test if it works better. but the problem is i cant figure out how to make the navmesh agent utilize the new points.

    the logic is basically the following:
    - if the path has more 3 or more corners i take the corner points of the calculated path of the navmesh agent and put them in an array
    - i calculate a bezier curve between the first 3 points to make it extruding and fitting around the corners.
    - i visualize the new points via gizmos and it looks good.
    - next i found out that i cant just set the corners of the path so i tried different things:
    1. i tried to change the corner points of the path directly, as was suggested in another thread about the topic. but thats not working anymore (at least not for me). i can set the points and dont receive any errors but when i check the points directly after setting them (one line later) then the point didnt change at all, no matter if changing the whole vector or just x or y of it.
    2. i tried making a new navmesh path, calculated a path for the destination of the current path, set the corner points to the bezier list points and when i check those the points of the path and the list are identical but as soon as i want to set the current path to the new path either with agent.path = newpath or with agent.setpath(newpath) nothing happens. it returns true but the corner points are exactly the same as before.

    note: i have auto-repathing turned off for testing and it didnt change a thing. when resetting the path without reassigning it to the new one the path is empty, so it doesnt get recalculated / assigned from somewhere else.

    is there really no way for the navmesh agent to get a custom path somehow, even if i already have a path with correct values? i assume when assigning a path the navmesh agent somehow checks the new path and just overrides the values with "better" ones... which would make assigning custom paths impossible with unitys navmesh agent.

    i guess i have to write a custom movement agent now?
     
  4. unity_XcvZUzrkJ7ji7Q

    unity_XcvZUzrkJ7ji7Q

    Joined:
    Mar 17, 2019
    Posts:
    5
    oh btw i remember trying to get the aron granbergs pathfinding to work with your navmesh but that didnt really work out well and i was having trouble setting up links between grids for npc teleportation purposes via runtime and after testing your navmesh stuff everything was so easy that i never looked back :D
     
  5. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @unity_XcvZUzrkJ7ji7Q,

    I don't have answer to you. Writing custom Agent is a bit of a challenge.
    But if Unity Agent doesn't work for you, it worth a try.

    And back to "aron granbergs pathfinding", you may try to adapt his agent to your needs.
     
  6. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Hi @vhman, sorry I have to ask you again.
    So in my project the AI looks fine, even when I'm changing the agent by code.

    But there's a problem when I'm trying to implement a new behaviour for a new AI.
    I have a custom bake surface for a specific agent type, so I set the agent type for the new AI, but the AI does not show when I'm playing the scene. But the AI show just fine when I'm using the humanoid agent type.

    So I decided to try it in a new project, but the AI not showing even though it's humanoid.

    Any ideas?
     
  7. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Here I give the screenshot.
    The circle NPC is not "behind" the tilemap, it's somehow hidden.
     

    Attached Files:

  8. Shiina011

    Shiina011

    Joined:
    Oct 1, 2020
    Posts:
    46
    Ok, so it's a stupid problem.
    I forgot to put the code required in the "start" method (updateRotation, etc.).

    So yeah, it's solved. Sorry if I'm just flooding the thread with a stupid question lol.
     
    vhman likes this.
  9. CNibbles

    CNibbles

    Joined:
    May 11, 2017
    Posts:
    7
    Hi there @vhman , I have this weird issue when using the h8man/NavMeshPlus. The github pointed here to discuss, so I was wondering if anyone else had this issue. When setting the position around a corner/near a corner, the agent gets stuck and moves very slowly to the destination. I am not doing anything complicated or hard in code, just where the player clicks, set destination of the navmesh to there.

    Here's a gif as an example:

    https://i.imgur.com/QO8bOR1.gif

    And another one. The white line is from the agent to the end point

    https://i.imgur.com/m1teWHs.gif
     
    Last edited: Jul 24, 2021
  10. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @CNibbles, Hello.

    Nope, you are not the only one. Few posts up, also the same issue. I think I saw this issue in general discussions on NavMesh.AI

    I never had this issue, so I have no idea why it happens. Also, NevMeshPlus is only proxy to bake the mesh, afterward its unity job.

    @unity_XcvZUzrkJ7ji7Q, did you solve your issue?

    With quick googling I found few possible workarounds:

    https://www.reddit.com/r/Unity3D/comments/4rgmm6/why_does_my_nav_mesh_agent_slow_down_around_the/

    SOLVED - If I turn the Obstacle Avoidance Quality to None, it seems to just perfectly follow the path.

    https://forum.unity.com/threads/nav-mesh-agent-slow-down-in-the-corners-overlap.570754/

    - If I use obstacle avoidance : Quality : None
    Speed in the corners is no longer decreases

    https://issuetracker.unity3d.com/is...ing-a-small-gap-when-using-obstacle-avoidance
     
  11. CNibbles

    CNibbles

    Joined:
    May 11, 2017
    Posts:
    7
    It is strange. I've tried to debug it for a few hours, but everything in terms of the agent movement/paths seems normal. I've also noticed the agent's Z moves ever so slightly with the Y, so it could be just a side effect of the proxy you've made. If I figure out a fix, I'll post it here
     
  12. KlaudiaMK

    KlaudiaMK

    Joined:
    Feb 17, 2021
    Posts:
    1
    Hey!
    Could you explain how to build at runtime?
     
  13. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
  14. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @KlaudiaMK,

    I just looked into the code and documentation, and found that you need to call a single method to bake at runtime
    This method, you can call it on Start(), or if you prefer colliders on LateUpdate()
    Code (CSharp):
    1. public AsyncOperation BuildNavMeshAsync()
    (see notes https://github.com/h8man/NavMeshPlus/wiki/HOW-TO#use-geometry)

    And if you need update use this one:
    Code (CSharp):
    1.         public AsyncOperation UpdateNavMesh(NavMeshData data)
    but it does not cache sources, so you might use its internal method
    Code (CSharp):
    1.  NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, sourcesBounds);
    hope it helps
     
  15. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
  16. nubbyninja

    nubbyninja

    Joined:
    May 16, 2019
    Posts:
    24
    Unable to bake nav mesh. Tried clearing nav mesh and baking too, to no avail. Getting a null from the inspector for the nav mesh data.

     
    Last edited: Sep 25, 2021
  17. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @nubbyninja , Hi!

    I don't how it can happen, cause builder does check tile node before getting any info to avoid nulls.
    Anyway, I add second check that will fix this particular exception, so download new sources from github.

    Thank you for feedback!
     
  18. nubbyninja

    nubbyninja

    Joined:
    May 16, 2019
    Posts:
    24
    Thank you! Will try it out momentarily.
     
  19. Juice-Tin

    Juice-Tin

    Joined:
    Jul 22, 2012
    Posts:
    234
    Hi, I can't seem to find much info, but will this generate on the top of 2D platforms? (Like oldschool Mario Brothers)
    So basically identical to the current navmesh, but able to generate on top of 2D sprites instead of 3D blocks.

    Or is it only meant to generate as a floor around other objects, like for top-down games?
     
  20. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    Hello @Juice-Tin

    This component is made toward top-down games, and doesn't support platformers.
     
  21. AItima

    AItima

    Joined:
    Jul 28, 2018
    Posts:
    2
    Hello, Thank you for fantastic Navmesh plus.

    I have a problem that need some help. I tried to program my AI to find the closest target by checking if the target if available and calculate the distance between target and the AI.

    The problem is that Navmesh.CalculatePath always return invalid for unknown reason while setDestination is working totally fine.

    I tried fix it for a while and got it to work afterI bake NavMesh again but after that when the first target disappear or the AI teleport from enemy it stops working CalculatePath always return false again.
     
  22. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @Kae-am,

    It is not well documented, at least not in explicit way, but you must supply NavMeshQueryFilter all data, including cost.
    Or, if you want to simply check "is there a path?" use NavMesh.CalculatePath(transform.position, target.position, NavMesh.AllAreas, path);

    1) Verify that you are using NavMesh.AllAreas
    2) Make sure that points are on a mavmesh plain. (z equals 0)

    Unfortunately I lost my working example, but if you still would have any troubles, leave a message, I will try to help you.
     
  23. AItima

    AItima

    Joined:
    Jul 28, 2018
    Posts:
    2
    Thank you a lot! Everything is working correctly now. I will let you know if I run into any problem in the future. Your addon is fantastic!
     
    vhman likes this.
  24. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    Hi - currently using NavMeshPlus, I have an issue where the enemy stops chasing, or at least starts moving super slow. I build the navmesh fine, and the test AI code is as follows. Anything obvious amiss in the code? I can also send you a test project if you have time to take a look at the issue.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.AI;
    4.  
    5. public class SimpleAI : MonoBehaviour
    6. {
    7.     [Header("Movement Settings")]
    8.     [SerializeField] float moveSpeed = 1f;
    9.     [SerializeField] float maxMoveSpeed = 1.5f;
    10.     [SerializeField] float chaseMultiplier = 2f;
    11.  
    12.     [Header("Distance Settings")]
    13.     [SerializeField] float viewDistance = 7.5f;
    14.     [SerializeField] float minDistance = 0.5f;
    15.     [SerializeField] float attackDistance = 1.5f;
    16.  
    17.     private NavMeshAgent m_navMeshAgent;
    18.     private Transform playerTarget;
    19.     private Vector2 playerPos;
    20.     private Vector2 targetPos;
    21.     private Vector2 relativePos;
    22.     private Vector2 relativeTargetPos;
    23.     private float distance;
    24.     float finalMoveSpeed;
    25.  
    26.     void Start()
    27.     {
    28.         // Setup the NavMeshAgent
    29.  
    30.         m_navMeshAgent = GetComponent<NavMeshAgent>();
    31.  
    32.         if (maxMoveSpeed > moveSpeed)
    33.         {
    34.             // If the Max Move Speed is great than Move Speed, then return a random Final Move Speed between the two
    35.             // If the Chase Multiplier is greater than 1, multiply the Final Move Speed by the Chase Multiplier
    36.  
    37.             if (chaseMultiplier > 1f)
    38.             {
    39.                 finalMoveSpeed = Random.Range(moveSpeed, maxMoveSpeed) * chaseMultiplier;
    40.             }
    41.             else
    42.             {
    43.                 finalMoveSpeed = Random.Range(moveSpeed, maxMoveSpeed);
    44.             }
    45.         }
    46.         else
    47.         {
    48.             // If there is no Max Move Speed, then code uses the Move Speed, and again checks if there is a Chase Multiplier
    49.  
    50.             if (chaseMultiplier > 1f)
    51.             {
    52.                 finalMoveSpeed = moveSpeed * chaseMultiplier;
    53.             }
    54.             else
    55.             {
    56.                 finalMoveSpeed = moveSpeed;
    57.             }
    58.         }
    59.  
    60.         if (m_navMeshAgent != null)
    61.         {
    62.             playerTarget = GameObject.FindWithTag("Player").transform;
    63.             m_navMeshAgent.updateRotation = false;
    64.             m_navMeshAgent.updateUpAxis = false;
    65.             m_navMeshAgent.speed = finalMoveSpeed;
    66.         }
    67.     }
    68.  
    69.     void Update()
    70.     {
    71.         // Distance to player calculations
    72.  
    73.         playerPos = playerTarget.position;
    74.         relativePos = playerPos - (Vector2)transform.position;
    75.         distance = relativePos.magnitude;
    76.         transform.position = new Vector3(transform.position.x, transform.position.y, 0f);
    77.  
    78.         if (distance > attackDistance)
    79.         {
    80.             if (m_navMeshAgent != null)
    81.             {
    82.                 m_navMeshAgent.destination = playerTarget.position;
    83.             }
    84.         }
    85.         else
    86.         {
    87.             // Attack when player is within Attack Range
    88.             // Attack code here
    89.  
    90.             Debug.Log("Attack");
    91.         }
    92.  
    93.         // Rotate the enemy to face the target
    94.  
    95.         float angle = Mathf.Atan2(relativePos.y, relativePos.x) * Mathf.Rad2Deg - 90f;
    96.         transform.rotation = Quaternion.Euler(0f, 0f, angle);
    97.     }
    98. }
     
  25. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    A bit more info on the issue - I run away from the AI down screen, it follows fine, until occasionally the Agent just stops, or perhaps just moves very slow.

    If the player then changes direction and moves left or right, the AI wakes up and resumes chasing as it should.
     
  26. sammarin

    sammarin

    Joined:
    Oct 14, 2019
    Posts:
    4
    Hi,

    First thanks for this great package!

    It seems I have a similar problem than @supericon .

    In my little game, the agent (the zombie) regularly recalculates a new path towards the target (the player). But whenever the agent is chasing the target vertically, at some point, the agent seems to be stucked and only moves super slowly. This issue only seems to appear when the agent moves vertically. If the target moves a little bit on the left or right, the chasing resumes correcly.

    FYI, I am using the setCalculatePath and SetPath functions and I'm using NavMeshPlus 0.1.0.

    I made a video to illustrate the problem:


    Any idea?
    Thanks,
    Regards,
    Sam
     
  27. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    Hi Sam - yep, sounds like the same thing - vertical player movement, AI agent chasing, often the AI just stops after a while and then moves super slow, but if you move left or right, the AI agent wakes up and resumes the chase.
     
  28. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
  29. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    On the x? Like this:

    m_navMeshAgent.destination = playerTarget.position + new Vector3(0.0001f, 0f, 0f);

    Although, I tried it on all axis just to be sure, and it doesn't fix it :(
     
  30. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @supericon ,

    Send my a test project, as you mentioned earlier, I would take a look.
    But, that 100% not NavMeshPlus issue, so while I'm trying to find what's happening, keep looking inside https://forum.unity.com/forums/navigation.79/

    Try to reach Unity staff if you are lucky)
     
  31. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    Thanks :) That would be awesome - test project sent via DM.
     
    vhman likes this.
  32. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    Quick update.

    I didn't find issue to be caused by direction of the agent to target, but the agent in 95% stuck on the same spot of the navmesh. I'm trying to output Agent path state to catch what is happening, but with no luck.

    So, I found workaround that I was talking about, but its should not be a constant, rather function.
    The simplest solution is to add drift to the target position

    Code (CSharp):
    1.    var agentDrift = 0.1f;    
    2.    var driftPos = playerTarget.position + (Vector3)(agentDrift * Random.insideUnitCircle);
    3.    var res = m_navMeshAgent.SetDestination(driftPos);
    Also issue can be caused by re-path on every frame. I will test and reply shorty
     
    Last edited: Dec 22, 2021
    Lowrc and supericon like this.
  33. sammarin

    sammarin

    Joined:
    Oct 14, 2019
    Posts:
    4
    Hi @vhman and @supericon,

    I also implemented a workaround. I'll explain to you here:
    • The problem seems to happen when velocity.x of the navmesh agent is equal to 0
    • So in the update function, at each frame I test if the velocity.x of the navmesh agent is equal to 0
    • If this is the case, I recalculate a new path for the agent (using CalculatePath and SetPath) but with a target position.x to which I add 0.2f
    • That way, velocity.x of the agent ceased to be 0 so the agent can keep going walking on the newly defined path (which goes a little to the right)
    Of course, that way, the agent will sometimes slightly moves a little on the right while chasing the target but since I recalculate regurlarly the path (for example every second), the global behaviour is still OK
     
    supericon, vhman and DungDajHjep like this.
  34. supericon

    supericon

    Joined:
    Feb 15, 2013
    Posts:
    63
    Thanks @vhman & @sammarin - that is amazing. Must admit, I took a few days off over Christmas, so haven't had a chance to test, but I shall update the code and take a look. Thanks again guys :)
     
  35. g3trans

    g3trans

    Joined:
    Apr 23, 2018
    Posts:
    3
    Does anyone know why having a rigidbody2d would cause my baked nav mesh to have an offset?

    Sorry for the bad resolution:
    https://imgur.com/a/HUezbUN

    Thanks for the asset vhman, you rock.
     
  36. Lowrc

    Lowrc

    Joined:
    Aug 29, 2017
    Posts:
    1
    Thanks for the quick fix ! And ofcourse thanks for your super asset, really great stuff, man!

    Been trying to solve the same issue (mentioned by @supericon and @sammarin) by means of rigidbody, trying to put force.impulse to it at every start of the pathfinding, but this is certainly NOT the way to go :D

    Also, your quick fix had some minor, solvable implication for my check of arrival at the targetpoint, solved it by minimalizing the drift (0.0001) and getting a minimal stopping distance (0.1). To whom it may concern, code below..

    Happy New Year !

    Code (CSharp):
    1.  
    2.     void StartMovement(GameObject target)
    3.     {
    4.         // Quick fix of vhman !
    5.         var agentDrift = 0.0001f; // minimal
    6.         var driftPos = target.transform.position + (Vector3)(agentDrift * Random.insideUnitCircle);
    7.         agent.SetDestination(driftPos);
    8.     }
    9.  
    10.     void CheckArrival()
    11.     {
    12.         // Check if we've reached the destination
    13.         if (!agent.pathPending)
    14.         {
    15.             if (agent.remainingDistance <= agent.stoppingDistance) //  stoppingDistance minimally set in editor to 0.1f
    16.             {
    17.                 if (!agent.hasPath || agent.velocity.sqrMagnitude == 0f)
    18.                 {
    19.                     arrived = true;
    20.                 }
    21.             }
    22.         }
    23.     }
    24.  
     
    vhman likes this.
  37. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    Hello,

    It seems to be a bug in matrix calculation. I will take a look in a few days.

    @Lowrc I will add it to wiki cause its trouble to search for the same topic every time, thx
    @sammarin if you have snippet, please post it below, I will add it too
     
    Last edited: Dec 31, 2021
    Lowrc likes this.
  38. g3trans

    g3trans

    Joined:
    Apr 23, 2018
    Posts:
    3
    I haven't seen the fourth one, but a bug in the matrix is definitely something to worry about.

    By the way, I'm on 2020.3.24f1, let me know if you need more information. Thanks!
     
    Lowrc likes this.
  39. g3trans

    g3trans

    Joined:
    Apr 23, 2018
    Posts:
    3
    Does anyone know what this piece of code does?

    Code (CSharp):
    1.  
    2.             if (collider.attachedRigidbody)
    3.             {
    4.                 Vector3 scaled = Vector3.Scale(collider.transform.position, builder.overrideVector);
    5.                 src.transform = Matrix4x4.TRS(scaled, collider.transform.rotation, Vector3.one);
    6.             }
    7.             else
    8.             {
    9.                 src.transform = Matrix4x4.identity;
    10.             }
    Why would my polygonCollider2d having a rigidbody affect it's location?

    This is what is making my navmesh bake in the wrong location.

    builder.overrideVector = "(1.0, 1.0, 1.0)"
    collider.transform.position = "(-0.3, 0.6, -0.1)"

    scaled does not change as result of scaling, it stays
    scaled = "(-0.3, 0.6, -0.1)"

    src.transform.toString() = "1.00000\t0.00000\t0.00000\t-0.27274\n0.00000\t1.00000\t0.00000\t0.59669\n0.00000\t0.00000\t1.00000\t-0.06651\n0.00000\t0.00000\t0.00000\t1.00000\n"

    I don't quite understand what's the purpose of the TRS method.

    Now that I inspect it's manual, the TRS specification is:
    Code (CSharp):
    1.  
    2.         [FreeFunction("MatrixScripting::TRS", IsThreadSafe = true)]
    3.         public static Matrix4x4 TRS(Vector3 pos, Quaternion q, Vector3 s);
    4.  
    While the NavMeshBuilder2d is the other way around, the scale is the first parameter and what I assume would be the translation in third param.
     
  40. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
  41. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    Also note that the call here stops the pre-multiplication of the mesh to be in world-space i.e. it's in local-space. If both of these are on then the mesh will be in world-space already. Scaling is already pre-applied in both cases because each collider has its own special rules on how scaling is applied for example, a circle cannot be scaled in non-uniform way to make it become an ellipse.

    Setting both of those bools in the Collider2D.CreateMesh call to be true and using Matrix4x4.identity for the transformation should work in theory although I am not massively familiar with this package and what that'd do.

    Certainly you can run your own test will any collider to check the above call and its functionality.
     
    vhman likes this.
  42. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    Hello @g3trans

    I played for few hours in troubleshooting. I noticed that rigid body and collider are not the same objects so I was able to reproduce it quickly, but that I stuck.

    collider.CreateMesh(true, true) didn't give me desired result, as 2 duplicated objects with different rigid-body had the same Hash. So it bakes wrong mesh. Maybe it's a fluke?

    Than I read documentation!
    useBodyPosition:
    // Should the mesh be transformed by the position of the attached Rigidbody2D?

    So of course you should not use collider for matrix transformation but rigid-body!

    Issue fixed for now. Code should be available on GitHub page.
     
  43. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    If you're referring to the API call Collider2D.GetShapeHash then know it's not related to the mesh output of CreateMesh but as the docs state, the shapes (geometry) inside the collider so it identifies that. It's not a unique collider specific one. The same shape or set of shapes produce the same hash which is why it's specifically called "shape hash". :) You can use it to see if the collider has changed its geometry in any way or compare it against another collider to see if it's the identical geometry.

    Two different colliders each with a circle with the same offset and radius would be the same for instance because they both have the exact same shape geometry.

    If you wanted to make it collider specific then just rehash it against something unique to that object such as the .Net object hash or its Unity instanceID.

    Side-Note: The shape hash has been made a lot quicker now as it's calculated as the shapes are created and then persisted rather than calculated from scratch when you call it. I cannot remember the versions that landed right now but it's in the release notes.

    Hope that helps.
     
  44. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    @MelvMay,

    I have at least 4 "Stones" with box collider 1 by 1, two of which have rigid body. And Hash is unique for each of stones. But if I duplicate those stones (now its 8 objects), only stones with rigid body have the same Hash, while stones without rigid body are unique.

    Case1: "Stones" without rigid body are unique - yes, as it has its own matrix, so we supply Matrix4x4.Identity (that's fine)
    Case2: "Stones" with rigid body unique - why? it is the same box collider but with rotation and rotation is applied afterward in my own matrix.

    Behavior of Hash is kind of tricky. I use it only for cache, so it dies not disrupt functionality.

    upload_2022-1-19_13-24-56.png
     
  45. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    Yes because not having a Rigidbody2D means the collider geometry is different because all collider geometry is relative to the body it is attached to. If this wasn't the case then anytime something moved, all the geometry would have to be recalculated which would be expensive and not work at all at scale.

    Unity lets you omit a Rigidbody(2D) to make it implicitly Static (personally I've never liked this). When you do that, we create it against the hidden static ground-body that lives at the world origin with no rotation. This means its local-space is the same as its world-space so it's created at that position/rotation. As a side-note, this is why moving such an implicitly Static 2D Collider is bad; we have to recreate its geometry at the new position but it's Static meaning non-moving so it's only a performance problem if you move it. It's like screwing two bits of wood together then wanting to move one and thinking, this is inconvenient. ;)

    Anyway, when moving a Rigidbody2D, the geometry doesn't have to change because it's relative to that.

    For example, take a GameObject with a Transform at (10,20,0). Add a Rigidbody2D and a CircleCollider2D with no offset; the circle physics shape geometry has a position of (0,0) as it's relative to the body position. Instead, don't add a Rigidbody2D but just a CircleCollider2D (again, with no offset); the circle physics shape geometry has a position of (10,20). Different!

    In short, a Collider not attached to Rigidbody2D has different geometry than one that is attached in terms of the physics shapes inside it and their vertex content.

    In 2021.2 onwards, you can actually read these physics shapes using GetShapes so can verify this yourself. It works with the new PhysicsShapeGroup2D and CustomCollider2D.
     
    LE_JUICEMEISTER and vhman like this.
  46. EricChan13412

    EricChan13412

    Joined:
    Mar 29, 2021
    Posts:
    3
    Hi, I am using the following config:
    upload_2022-1-29_23-19-7.png

    If I paint the collider to the tilemap by hand and hit Bake, it will work:
    upload_2022-1-29_23-19-40.png

    But when I update the tilemap by code and call `BuildNavMeshAsync()` in runtime, it looks like the newly added tiles are not taken into account. Do you know what I did wrong?
    upload_2022-1-29_23-24-31.png
     
  47. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    Have the tiles been added to the collider yet? The Tilemap queues tile changes and limits how many per-frame so you don't get massive spikes. Doing everything synchronously can be expensive if you're change a lot of tiles.

    You can see those in the API here. It provides the ability to see if there are changes, how many before a full rebuild occurs and the ability explicity process tilemap changes.
     
  48. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
    Hello @EricChan13412

    I believe you changed tilemap and bake immediate, while collider geometry update later on a frame (or even after few? not confirmed).
    Consider to update navmesh after geometry had changed, as @MelvMay mentioned you can check it in coroutine or force change immediately.

    Also there some notes form manual, if it makes sense:

    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()' if you baking navmesh at runtime.

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

    More samples can be found in "NavMeshComponents" repository on GitHub and NavMeshBuilder methods documentation at Unity site
     
  49. chunky_octopus

    chunky_octopus

    Joined:
    Apr 11, 2015
    Posts:
    14
    Hi guys, despite reducing my agent radius to the minimum, I can't manage to reduce the gap between the graphics and the mesh (as shown in the figure).

    Any idea?
     

    Attached Files:

  50. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    335
Thread Status:
Not open for further replies.