Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Bug Unity crash when using OverlapSphereCommand

Discussion in 'Physics' started by Saltant, Apr 8, 2024.

  1. Saltant

    Saltant

    Joined:
    Aug 15, 2018
    Posts:
    7
    Hi, im using Unity 2022.3.22f1 (LTS) and create a system to find enemies (RTS game), in Update for each unit I call the FindEnemyAsync() method which uses Jobs to execute OverlapSphereCommand, but my code causes Crash unity editor (in build the same, crash build), what am I doing wrong, or what is the problem?
    Code (CSharp):
    1.  
    2.     public void FindEnemyAsync()
    3.     {
    4.         if (!IsSpawned || IsHasEnemy) return;
    5.  
    6.         var commands = new NativeArray<OverlapSphereCommand>(1, Allocator.TempJob);
    7.         var results = new NativeArray<ColliderHit>(3, Allocator.TempJob);
    8.         queryParameters = new QueryParameters
    9.         {
    10.             layerMask = visionLayerMask,
    11.             hitTriggers = QueryTriggerInteraction.Collide,
    12.         };
    13.         commands[0] = new OverlapSphereCommand(aiPath.position, unitData.Characteristics.ViewRadius, queryParameters);
    14.         OverlapSphereCommand.ScheduleBatch(commands, results, 1, 3).Complete();
    15.  
    16.         enemy = results.GetEnemy(aiPath.position);
    17.  
    18.         commands.Dispose();
    19.         results.Dispose();
    20.     }
    21.  
    =================================================================
    Native Crash Reporting
    =================================================================
    Got a UNKNOWN while executing native code. This usually indicates
    a fatal error in the mono runtime or one of the native libraries
    used by your application.
    =================================================================

    =================================================================
    Managed Stacktrace:
    =================================================================
    at <unknown> <0xffffffff>
    at Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete <0x000e0>
    at Unity.Jobs.JobHandle:Complete <0x000f2>
    at UnitObject:FindEnemyAsync <0x0085a>
    at TowerUnit:Update <0x0020a>
    at System.Object:runtime_invoke_void__this__ <0x00187>
    =================================================================
    Received signal SIGSEGV
    Obtained 30 stack frames
    0x00007ff79db5ed8d (Unity) ujob_execute_job
    0x00007ff79db60509 (Unity) ujob_wait_for
    0x00007ff79db5a7a7 (Unity) CompleteFenceInternal
    0x00007ff79d0b542f (Unity) JobHandle_CUSTOM_ScheduleBatchedJobsAndComplete
    0x000001c95b71f2a1 (Mono JIT Code) (wrapper managed-to-native) Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete (Unity.Jobs.JobHandle&)
    0x000001c95b71f113 (Mono JIT Code) Unity.Jobs.JobHandle:Complete ()
    0x000001c95e0cd23b (Mono JIT Code) UnitObject:FindEnemyAsync () (at C:/UnityProjects/Server/Assets/Scripts/UnitObject.cs:175)
    0x000001c95e0cb97b (Mono JIT Code) TowerUnit:Update () (at C:/UnityProjects/Server/Assets/Scripts/TowerUnit.cs:53)
    0x000001c9108adcb8 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    0x00007ff830524c1e (mono-2.0-bdwgc) mono_jit_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/mini/mini-runtime.c:3445)
    0x00007ff83045d254 (mono-2.0-bdwgc) do_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3068)
    0x00007ff83045d3cc (mono-2.0-bdwgc) mono_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3115)
    0x00007ff79df40c44 (Unity) scripting_method_invoke
    0x00007ff79df1e9b4 (Unity) ScriptingInvocation::Invoke
    0x00007ff79df061a4 (Unity) MonoBehaviour::CallMethodIfAvailable
    0x00007ff79df062ca (Unity) MonoBehaviour::CallUpdateMethod
    0x00007ff79d9991db (Unity) BaseBehaviourManager::CommonUpdate<BehaviourManager>
    0x00007ff79d9a073a (Unity) BehaviourManager::Update
    0x00007ff79dbd590d (Unity) `InitPlayerLoopCallbacks'::`2'::UpdateScriptRunBehaviourUpdateRegistrator::Forward
    0x00007ff79dbb4a3c (Unity) ExecutePlayerLoop
    0x00007ff79dbb4bb0 (Unity) ExecutePlayerLoop
    0x00007ff79dbbb445 (Unity) PlayerLoop
    0x00007ff79eb88955 (Unity) PlayerLoopController::InternalUpdateScene
    0x00007ff79eb9581d (Unity) PlayerLoopController::UpdateSceneIfNeededFromMainLoop
    0x00007ff79eb93b01 (Unity) Application::TickTimer
    0x00007ff79f00e67a (Unity) MainMessageLoop
    0x00007ff79f013550 (Unity) WinMain
    0x00007ff7a03f594e (Unity) __scrt_common_main_seh
    0x00007ff8dba77344 (KERNEL32) BaseThreadInitThunk
    0x00007ff8dd5226b1 (ntdll) RtlUserThreadStart
     
  2. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    850
    Could be related to this issue (marked as won’t fix due to failure to reproduce)
    https://issuetracker.unity3d.com/issues/crash-on-overlapspherecommandjob-when-entering-the-play-mode
    If you can create a reliable reproducing (“repro”) project, perhaps file a bug report with it.
     
    Saltant and apkdev like this.
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,992
    When you use jobs, give them time to complete in the background. You call Complete() on the job right away so the main thread has to wait for them (the one) to finish. At the least Complete() should be deferred to LateUpdate or the next frame.

    Then you are running a single command with at most three results. The whole point of batching is to run numerous commands in parallel, possibly dozens or hundreds, not just a single one. The effort to set this command up will likely be even higher than any benefit gained from running this jobified command.

    Practically speaking you are forfeiting most of the benefits of using jobs in the first place, so you could as well just use the non-batched, non-jobified OverlapSphere.
     
  4. Saltant

    Saltant

    Joined:
    Aug 15, 2018
    Posts:
    7
    As MYRON answered on the link in Issue Tracker, it was necessary to increase the number of maxHits when forming ScheduleBatch otherwise if the number of collisions is more than the maxHits set in ScheduleBatch - crash occurs. Although I think this behavior is considered a bug, because I specifically specify both the array size and the number of maxHits I want to get, other collisions should be ignored and not cause a crash.
     
    Spy-Master likes this.
  5. Saltant

    Saltant

    Joined:
    Aug 15, 2018
    Posts:
    7
    I have a hundred units in a level that are searching for a target, would it be beneficial to place these calls through the standard OverlapSphereNonAlloc in Update? Wouldn't this behavior result in lower fps than using Jobs in the backgroud?
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,417
    I think their point is that you're not doing it in the background with your current use of the API. You're immediately locking up the main thread. So right now you're not getting any advantage.
     
    Spy-Master likes this.
  7. Saltant

    Saltant

    Joined:
    Aug 15, 2018
    Posts:
    7
    I tried different variants of my task with Jobs (including the delayed call Complete() in the next frame) and it turns out that the usual OverlapSphereNonAlloc at 300 units on the scene is executed much faster than OverlapSphereCommand (apparently because the planning of the task, is more expensive than the task itself), as a result, on a scene with 300 units with Jobs I have 35 fps, and when using the usual raycast 100 fps.

    Indeed, there was a misunderstanding of how OverlapSphereCommand works in Jobs, i.e. it is reasonable to do it for example if a unit has to perform many operations in one frame, not one single raycast. If there are many operations - then you can apply Jobs by scheduling a whole array in OverlapSphereCommand.ScheduleBatch.