Hello, I recently started to learn about ECS and I’m currently trying to figure out the/a proper way to create GPU skinned characters where I update bone matrices in jobs. I started looking into the GPU Character Package here (GitHub - joeante/Unity.GPUAnimation: Simple but very fast GPU vertex shader based animation system for Unity.Entities).
Currently I set a Dynamic Buffer with float4x4s for each bone per character to each Character Entity like this:
var boneMatrices = BoneMatrixUtility.UpdateBoneMatrices(renderer, renderer.bones);
var buffer = manager.AddBuffer<BoneBufferElement>(entity);
foreach (var m in boneMatrices)
buffer.Add(new BoneBufferElement() {Value = m});
Q1: I dont need a resizeable container but I havent figured out yet how to put an writeable array (other than a DynamicBuffer) inside an IComponentData (should I better use BlobArray?)
I’m able to pass that to the shader in the GPU Character Render System via ComputeBuffer and Reinterpreting the DynamicBuffer to a NativeArray.
Q2: But how do I update the DynamicBuffer (or NativeArray) from a Job before passing it to the shader. I just tried the following:
[UpdateBefore(typeof(GpuCharacterRenderSystem))]
public class BoneSystem : JobComponentSystem
{
public struct BoneUpdate : IJobForEachWithEntity<LocalToWorld>
{
public BufferFromEntity<BoneBufferElement> Buffer;
public float time;
public void Execute(Entity entity, int index, [ReadOnly] ref LocalToWorld c0)
{
var buffer = Buffer[entity];
for (var i = 0; i < buffer.Length; i++)
{
var val = buffer[i];
val.Value.c3.y += math.sin(time * (index+1) / 2f * i) * .5f;
buffer[i] = val;
}
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var job = new BoneUpdate()
{
time = Time.time,
Buffer = GetBufferFromEntity<BoneBufferElement>()
};
var handle = job.Schedule(query, inputDeps);
return handle;
}
private EntityQuery query;
protected override void OnCreate()
{
base.OnCreate();
query = EntityManager.CreateEntityQuery(
ComponentType.ReadOnly<BoneBufferElement>()
);
}
}
but I get:
The container does not support parallel writing. Please use a more suitable container type.
Unity.Jobs.LowLevel.Unsafe.JobsUtility.CreateJobReflectionData (System.Type wrapperJobType, System.Type userJobType, Unity.Jobs.LowLevel.Unsafe.JobType jobType, System.Object managedJobFunction0) (at <86888d7bf865490ca0c08194bf6338db>:0)
Any help is greatly appreciated