I’m trying to get my head around the basics of the ECS. While trying to understand how ISharedComponentData works I ran into some issues. I get this error message after starting play mode:
ArgumentException: SomeSystem:data SharedComponentDataArray<> must always be injected as [ReadOnly]
That’s the code:
using System;
using Unity.Entities;
public class SomeSystem : ComponentSystem
{
struct Data
{
[ReadOnly]
public SharedComponentDataArray<SomeSharedComponent> someSharedData;
}
[Inject] Data data;
protected override void OnUpdate()
{
// do something
}
}
[Serializable]
public struct SomeSharedComponent : ISharedComponentData
{
public float someValue;
}
Am I doing something wrong or is it a bug? With non-shared data (ComponentData and ComponentDataArray) it works.
AddCellLinkSystem:_data SharedComponentDataArray<> must always be injected as [ReadOnly]
internal struct Data
{
public EntityArray NewEntities;
[ReadOnly]
public ComponentDataArray<AddCellFlag> DatasForAdd;
[ReadOnly]
public ComponentDataArray<CellValue> CellValues;
[ReadOnly]
public SharedComponentDataArray<MapIVData> MapIVDatas;
public int Length;
}
[Inject]
private Data _data;
The MeshInstanceRenderer is an ISharedComponentData component, and thus can have reference data (this restricts or eliminates it’s ability to be modified on a job). This restriction means that the SharedComponentDataArray is effectively read-only by default.
Your main option is to track the changes some other way (via a different component that maps to the various MeshInstanceRenderes) and update the MIR state in a ComponentSystem (use the PostUpdateCommands to reassign the data).
Another option, you can try to use EntityCommandBuffer or EntityCommandBuffer.Concurrent to buffer the changes to a barrier system (EndFrameBarrier is a good choice) so that the changes will happen on the main thread, but can be buffered on your job thread.
If I’m to understand, there is no way to modify it in place and you’d have to use something like CommandBuffer.SetSharedComponent and erasing the previous one with an updated one?
I’m also not succeeding at changing/updating a material. Can’t create or modify a material even in a local variable while in a job. I’m a lill puzzled as how to proceed now.
In my job:
Material updatedMat = new Material(meshInstanceRenderer.material); // Copy the previous material
updatedMat.mainTexture = setDynamicTexture.Texture; // Change its texture to a new one
CommandBuffer.SetSharedComponent(entity, new MeshInstanceRenderer { mesh = meshInstanceRenderer.mesh, material = updatedMat });
Holy crap and it was bugging me that i cant seem to spawn stuff in parallel and although i was sure i was missing something, made no sense to me.
Thanks people