Alright, I have attached a repro case. Here is the system code directly:
using System.Diagnostics;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Physics.Systems;
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateBefore(typeof(BuildPhysicsWorld))]
public class TerrainColliderUpdateSystem : SystemBase
{
EntityQuery query;
private struct UpdateTerrainColliderJob : IJobEntityBatch
{
[ReadOnly] public ComponentTypeHandle<PhysicsCollider> PhysicsColliderTypeHandle;
public BufferTypeHandle<HeightElement> HeightsTypeHandle;
[BurstCompile]
public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
{
var physicsColliders = batchInChunk.GetNativeArray(PhysicsColliderTypeHandle);
var heightsBuffers = batchInChunk.GetBufferAccessor(HeightsTypeHandle);
for (int i = 0; i < batchInChunk.Count; i++)
{
var collider = physicsColliders[i];
var heightsBuffer = heightsBuffers[i];
var colliders = Unity.Physics.TerrainCollider.Create(
heightsBuffer.Reinterpret<float>().AsNativeArray(),
new int2(ReproSetup.Resolution),
new float3(1),
Unity.Physics.TerrainCollider.CollisionMethod.Triangles
);
collider.Value.Dispose();
collider.Value = colliders;
}
}
}
protected override void OnCreate()
{
query = GetEntityQuery(typeof(PhysicsCollider), typeof(HeightElement));
}
protected override void OnUpdate()
{
var mode = ReproSetup.Mode;
Dependency.Complete();
var stopWatch = new Stopwatch();
stopWatch.Start();
if (mode == SystemMode.ForEach)
{
Entities
.WithBurst()
.ForEach((ref PhysicsCollider collider,
ref DynamicBuffer<HeightElement> heightsBuffer) =>
{
var colliders = Unity.Physics.TerrainCollider.Create(
heightsBuffer.Reinterpret<float>().AsNativeArray(),
new int2(ReproSetup.Resolution),
new float3(1),
Unity.Physics.TerrainCollider.CollisionMethod.Triangles
);
collider.Value.Dispose();
collider.Value = colliders;
}).ScheduleParallel();
}
else
{
var job = new UpdateTerrainColliderJob
{
PhysicsColliderTypeHandle = GetComponentTypeHandle<PhysicsCollider>(),
HeightsTypeHandle = GetBufferTypeHandle<HeightElement>(),
};
// Split the chunk up for parallel processing
Dependency = job.ScheduleParallel(query, 4, Dependency);
}
Dependency.Complete();
stopWatch.Stop();
UnityEngine.Debug.Log($"System Execution Time: {stopWatch.ElapsedTicks / 10000.0f}");
}
}
In the SampleScene, the “ReproSetup” game object has a selector to run as “For Each” or “Job”. With “For Each” selected, the workload runs successfully. You can even see that the frametime reduces significantly if you set the InternalCapacity attribute on the DummyElement.cs to 3000 (just breaks up the chunk). So multi-threaded shape changes should work. However, with “Job” selected, we get the following error:
InvalidOperationException: The BlobAssetReference is not valid. Likely it has already been unloaded or released.
Unity.Entities.BlobAssetReferenceData.ValidateNonBurst () (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Entities/Blobs.cs:260)
Unity.Entities.BlobAssetReferenceData.ValidateNotNull () (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Entities/Blobs.cs:277)
Unity.Entities.BlobAssetReference`1[T].get_Value () (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Entities/Blobs.cs:365)
Unity.Physics.Broadphase+PrepareStaticBodyDataJob.ExecuteImpl (System.Int32 index, System.Single aabbMargin, Unity.Collections.NativeArray`1[T] rigidBodies, Unity.Collections.NativeArray`1[T] aabbs, Unity.Collections.NativeArray`1[T] points, Unity.Collections.NativeArray`1[T] filtersOut, Unity.Collections.NativeArray`1[T] respondsToCollisionOut) (at Library/PackageCache/com.unity.physics@0.6.0-preview.3/Unity.Physics/Collision/World/Broadphase.cs:831)
Unity.Physics.Broadphase+PrepareStaticBodyDataJob.Execute (System.Int32 index) (at Library/PackageCache/com.unity.physics@0.6.0-preview.3/Unity.Physics/Collision/World/Broadphase.cs:819)
Unity.Jobs.IJobParallelForDeferExtensions+JobParallelForDeferProducer`1[T].Execute (T& jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at Library/PackageCache/com.unity.jobs@0.8.0-preview.23/Unity.Jobs/IJobParallelForDefer.cs:62)
EDIT: This is the first error that appears in the log, there are many others afterwards, but I assume they are a result of this error.
7585135–940336–Project.zip (30 KB)