i need to pass data from mono to entity i created a buffer and filled it
class SpawnBot : UnityEngine.MonoBehaviour{
public GameObject Prefab;
public List<float3> ListBotPosition;
class SpawnBotBaker : Baker<SpawnBot>{
public override void Bake(SpawnBot authoring){
var e = GetEntity(TransformUsageFlags.None);
AddComponent(e, new SpawnBotComponent{ Prefab = GetEntity(authoring.Prefab, TransformUsageFlags.Dynamic) });
AddComponent(e, new SpawnBotUpdateNeedTag{});
var buffer = AddBuffer<BufferBotPosition>(e).Reinterpret<float3>();
foreach(var pos in authoring.ListBotPosition){
buffer.Add(pos);
}
}
}
}
public struct SpawnBotComponent : IComponentData{ public Entity Prefab; }
internal struct BufferBotPosition : IBufferElementData{ public float3 value; }
public readonly struct SpawnBotUpdateNeedTag : IComponentData, IEnableableComponent{}
next I need to extract these positions and create prefabs
public partial class SpawnBotSystem : SystemBase{
protected override void OnUpdate(){
var query = new EntityQueryBuilder(Allocator.Temp).WithAll<SpawnBotUpdateNeedTag>().WithAllRW<BufferBotPosition>().Build(EntityManager);
NativeArray<ArchetypeChunk> chunks = query.ToArchetypeChunkArray(Allocator.Temp);
for(int i = 0; i < chunks.Length; i++){ ReadBuffer(chunks[i]);}
chunks.Dispose();
}
private void ReadBuffer(ArchetypeChunk chunk){
BufferTypeHandle<BufferBotPosition> myElementHandle = GetBufferTypeHandle<BufferBotPosition>();
BufferAccessor<BufferBotPosition> buffers = chunk.GetBufferAccessor(ref myElementHandle);
for(int i = 0, chunkEntityCount = chunk.Count; i < chunkEntityCount; i++){
DynamicBuffer<BufferBotPosition> buffer = buffers[i];
for(int j = 0; j < buffer.Length; j++){
Debug.Log(">>>" + buffer[j].value);
// -> Instantiate To position "buffer[j].value"
// it was in the ISystem
// Entity newEntity = state.EntityManager.Instantiate(spawnBotComponent.ValueRO.Prefab);
// state.EntityManager.SetComponentData(newEntity, LocalTransform.FromPosition(buffer[j].value));
buffer.RemoveAt(j);
}
}
}
}
how to do it in systembase?
it’s just that in isystems, as I understand it, buffers cannot be used …
public void OnUpdate(ref SystemState state) {
EndSimulationEntityCommandBufferSystem.Singleton commandBufferSystem = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
EntityCommandBuffer commandBuffer = commandBufferSystem.CreateCommandBuffer(state.WorldUnmanaged);
// Use commandBuffer here. Pass it to your methods.
// I use it like this
SomeJob job = new() {
...
commandBuffer = commandBuffer.AsParallelWriter()
};
state.Dependency = job.ScheduleParallel(this.query, state.Dependency);
}
I’m sorry but I don’t understand, I’m just new to entities… I need to transfer values from an already created buffer and not create a new buffer, or how it works, I don’t understand yet …
and the old function seems to be how to pass singlets inside
public void OnUpdate(ref SystemState state){
var ecbSingleton = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
var job = new SpawnBotUpdateJob{
ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter()
};
state.Dependency = job.ScheduleParallelByRef(state.Dependency);
}
[WithAll(typeof(SpawnBotUpdateNeedTag))]
private partial struct SpawnBotUpdateJob : IJobEntity{
public EntityCommandBuffer.ParallelWriter ecb;
public void Execute([ChunkIndexInQuery] int chunkIndex, in Entity entity, in TargetLocation target, in LocalTransform transform){
............. maybe here call buffer?
}
}
maybe there already call a buffer somehow, I still don’t understand how it works …
I suggest you take another aproach to the problem. Instead of spawning gameobjects at first then transfering data from them to the newly spawned entities, the process should be like this:
Prepare a prefab entity (either by IBaker at baketime, or by EntityManager.CreateEntity at runtime)
Spawn some entities using that prefab entity, and set their components’ data
Collect data** from your entities, put them in some buffers
Spawn your gameobjects and apply these data to them
The idea is using GameObject only as a view - a place for you to dump the data from the ECS world. For me, this approach is much more intuitive. The ECS world would govern all data and logic, where as the GO world would only act as a view, a presenter for your data.
** You should only collect just enough data for the GOs, for they are just views, they won’t need everything.
Indeed this approach couldn’t solve more complicated problems like when the data would go back and forth between the 2 worlds. I haven’t reached that phase of my project yet, unfortunately.
my situation is as follows - the location data of objects is stored on the server, a mono object with a socket script makes a request to the server, receives data about where and what object is located, then this information needs to be transferred to entities and managed there already, and also after a certain time transmit data again in mono, mono in turn sends data again to the server…
(the transfer script and the server itself are already working, only with entities need to combine this …)
This changes nothing to my suggestion. You can think of the mono object that receives the server’s responses as another input interface. You’d likely have a place to receive user’s input and transfer that data to the ECS world too.
(The author doesn’t use Unity ECS but his own ECS solution, so you might get some hiccups reading his code. Just focus on the idea discussed in those articles.)
Might I know how your server is coded? I think it’s best to have your server coded in ECS too according all the information I’ve got from you up until now.
no, there is a regular dedicated server on Linux, the transmitter itself is written in PHP (ratchet), in fact it works as a transmitter in a chat, that is, it receives a string and sends it to other clients with the same session, well, plus a script that separately processes insert and read data from mysql database…
Unfortunately, in the server part, I’m still only in php …