Search Issue Tracker

By Design

Votes

1

Found in

2023.1.0b20

Issue ID

UUM-37973

Regression

No

Crash on NavMeshQuery::UpdateNeighbourLink when entering Play Mode in a project that uses NavMeshQuery from IJobForExtensions.ScheduleParallel and NativeDisableParallelForRestriction

-

Reproduction steps:
1. Open the attached “repro-project“
2. Open the Assets/Scenes/StinkyScene.unity scene
3. Enter Play Mode
4. Observe the crash

Reproducible with: 2023.1.0b20
Could not test with: 2021.3.27f1, 2022.3.1f1, 2023.2.0a18 (due to multiple errors in the Console)

Reproduced on: Windows 10 Pro

First few lines of the stack trace:
{{0x00007FFBF8DF03F9 (Unity) NavMeshQuery::UpdateNeighbourLink }}
{{0x00007FFBF8DF0A06 (Unity) NavMeshQuery::UpdateSlicedFindPath }}
{{0x00007FFBF7D5088A (Unity) NavMeshQuery_CUSTOM_UpdateFindPath }}
{{0x000001F42689D968 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.Experimental.AI.NavMeshQuery:UpdateFindPath (intptr,int,int&) }}
{{0x000001F42689D83B (Mono JIT Code) UnityEngine.Experimental.AI.NavMeshQuery:UpdateFindPath (int,int&)}}

  1. Resolution Note:

    The Unity engine cannot avoid this crash because the script code is intentionally overriding Unity's safety mechanisms.
    One single instance of a `NavMeshQuery` cannot be used in code that is being scheduled to run in parallel jobs. The pathfinding operations need to write data inside the NavMeshQuery buffer, so multiple jobs using the same query instance will overwrite each other's data in the same buffer, thus creating ideal conditions for a crash to happen. The error that shows up in the Console to prevent such a use case is: "queryInstance is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type". If the game script disables this check by calling `WithNativeDisableParallelForRestriction(queryInstance)` then the game is exposed to crashes.

    Here is in short how the faulty code looks like.
    NavMeshQuery queryInstance = new NavMeshQuery(.....);

    Entities
    .WithBurst()
    .WithNativeDisableParallelForRestriction(queryInstance)
    .WithAll<.....>()
    .ForEach((Entity e, .....) =>
    {
    .....

    status = queryInstance.BeginFindPath(fromLocation, toLocation, -1);
    .....

    status = queryInstance.UpdateFindPath(maxIterations, out int iterationsPerformed);
    .....

    status = queryInstance.EndFindPath(out int polygonSize);
    }).ScheduleParallel();

    To avoid the crash the script can be corrected in two ways:
    - Create a separate NavMeshQuery instance for each job or entity that is processed in parallel, and make sure each job uses a different query instance.
    or
    - Schedule the jobs to run single-threaded instead of in parallel.

    Side note: The experimental NavMeshQuery struct is being deprecated starting with 2023.2.0a22 due to deeper issues that require rework.

Comments (1)

  1. sleddingacrobat

    Jun 06, 2023 03:52

    Je vous remercie de l'information! Je cherchais et ne pouvait pas trouver. Vous me aidé!

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.