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?
public void FindEnemyAsync()
{
if (!IsSpawned || IsHasEnemy) return;
var commands = new NativeArray<OverlapSphereCommand>(1, Allocator.TempJob);
var results = new NativeArray<ColliderHit>(3, Allocator.TempJob);
queryParameters = new QueryParameters
{
layerMask = visionLayerMask,
hitTriggers = QueryTriggerInteraction.Collide,
};
commands[0] = new OverlapSphereCommand(aiPath.position, unitData.Characteristics.ViewRadius, queryParameters);
OverlapSphereCommand.ScheduleBatch(commands, results, 1, 3).Complete();
enemy = results.GetEnemy(aiPath.position);
commands.Dispose();
results.Dispose();
}
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.
at <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>
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.
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.
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?
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.
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.