I tried to write my version of CopyTransformToGameObjectSystem which also can do the same on request instead of every frame. It is just like CopyTransformToGameObjectSystem but it also handles entities with custom CopyTransformToGameObjectRequest.
[UpdateInGroup(typeof(TransformSystemGroup))]
public class CustomTransformSyncSystem : JobComponentSystem
{
private EntityQuery _transformSyncQuery;
protected override void OnCreate()
{
base.OnCreate();
_transformSyncQuery = GetEntityQuery
(
new EntityQueryDesc
{
All = new[]
{
ComponentType.ReadOnly<Transform>(),
ComponentType.ReadOnly<LocalToWorld>()
},
Any = new[]
{
ComponentType.ReadOnly<CopyTransformToGameObject>(),
ComponentType.ReadOnly<CopyTransformToGameObjectRequest>()
}
}
);
}
protected override Unity.Jobs.JobHandle OnUpdate(Unity.Jobs.JobHandle inputDeps)
{
var copyTransformsJob = new CopyTransforms
{
LocalToWorlds = _transformSyncQuery.ToComponentDataArrayAsync<LocalToWorld>(Allocator.TempJob, out inputDeps),
};
return copyTransformsJob.Schedule(_transformSyncQuery.GetTransformAccessArray(), inputDeps);
}
}
[BurstCompile]
struct CopyTransforms : IJobParallelForTransform
{
[DeallocateOnJobCompletion]
[ReadOnly] public NativeArray<LocalToWorld> LocalToWorlds;
public void Execute(int index, TransformAccess transform)
{
var value = LocalToWorlds[index];
transform.localPosition = value.Position;
transform.rotation = new quaternion(value.Value);
}
}
To make CopyTransformToGameObjectRequest one frame i use another system to cleanup entities with this component.
public class CopyTransformRequestCleanupSystem : SystemBase
{
private EntityQuery _cleanupQuery;
protected override void OnCreate()
{
base.OnCreate();
_cleanupQuery = GetEntityQuery
(
typeof(CopyTransformToGameObjectRequest)
);
}
protected override void OnUpdate()
{
EntityManager.RemoveComponent<CopyTransformToGameObjectRequest>(_cleanupQuery);
}
}
And if CopyTransformRequestCleanupSystem goes after CustomTransformSyncSystem it produces index out of range exception.
System.IndexOutOfRangeException: Index {0} is out of range of '{1}' Length.
Thrown from job: AssemblyCSharp.Assets.Source.Simulation.Test.CopyTransforms
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Burst -> Enable Compilation) to inspect full exceptions & stacktraces
The reason i tried to implement such system is that i recognized that some transform sync happens not immediately but in random moment. Trying to find issue i faced this.