Hello,
I’m going to make a game similar to tower defense. ECS seemed very suitable especially for war systems and I left OOP and turned to ECS.
Now I create a subscene and collect my building types there.
Just like in this video
i convert GameObject to Entity and load to dynamic buffer.
public class PrefabListAuthoring : MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity
{
public GameObject[] prefabs;
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
{
foreach (var prefab in prefabs)
{
referencedPrefabs.Add(prefab);
}
}
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var buffer = dstManager.AddBuffer<SpawnerListComponent>(entity);
foreach (var prefab in prefabs)
{
buffer.Add(new SpawnerListComponent { prefab = conversionSystem.GetPrimaryEntity(prefab) });
}
}
Buildings are loading into dynamic buffer and now I just want to change the spawnerComponent Value when I press a number and display a new object on the screen with Spawner. But I couldn’t even select the object yet. Can you help me?
PS By the way, this is not my ultimate goal of course. With Raycast, I will instatiate building where the mouse clicks.
Dynamic Buffer :
public struct SpawnerListComponent : IBufferElementData
{
public Entity prefab;
}
Component Data:
public struct SpawnerComponent : IComponentData
{
public Entity prefab;
}
Dynamic Buffer to Component Data load or selection system:
public partial class SpawnerControlSys : SystemBase
{
protected override void OnUpdate()
{
var e = GetSingleton<SpawnerComponent>().prefab;
var buffer = EntityManager.GetBuffer<SpawnerListComponent>(e);
if (Input.GetKeyDown(KeyCode.Alpha1))
{
Debug.Log("You pressed to Alpha1");
EntityManager.SetComponentData(e, new SpawnerComponent { prefab = buffer[0].prefab });
}
What do you mean by this?
The gameobject with SpawnerComponent prefab value is not changing. It only say none. I am trying to change that data and then create a system so I can spawn that prefab.
I still don’t think I understand what you are asking. But I’m going to take some stabs in the dark. Is your DynamicBuffer fully populated with non-Null entities?
Let me explain from top to bottom.
My main goal is to load different buildings into a dynamic buffer and then extract data from it and instantiate building with one spawner.
My approach is
- Converting Gameobject(Building) list to entity. MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity.
- Then load this GameObject(Building) list into a dynamic buffer. This part of script has already worked and when i look at the Debugger screen, GameObject(Building) list loaded to dynamic buffers and appeared.
- Then trying to load one building entity from the GameObject(Building) list that I have loaded into this buffer into spawner’s component data. (In this example, I tried to do it by pressing a number. But I will use the UI in the future.) I am trying to do this with a system. It didn’t work as I expected.
- Afterwards, constructing buildings on the screen with this spawner.
The missing part is to load any object from the GameObject (Building) list into the spawner component data(It is single object and I thought it can be a singleton) . When I press 1, Debug.Log appears, but the spawner component data prefab value does not change.
Maybe i’m thinking like an OOP guy because i did it like that: There is a Building List ( Scriptable object) (and then)=> a spawner object (and then)=> load to one of spawing building to this spawner object with UI (and then)=> click to screen (and then)=> instantiate building in the map.
I know you can do this task with blob asset but i don’t understand very well it and i am self-taught guy who is background 3d. It is hard and it is not like scriptable object. I find a blog which it tells scriptable object to blob asset.
If i can achieve that i won’t need this solution.
PS: Thank you.
Oh. I think I see your issue now. You are trying to set a new SpawnerPrefab component on the prefab currently held by the existing SpawnerPrefab singleton. Instead of GetSingleton().prefab, I think you want to use GetSingletonEntity(). I’m kinda surprised you didn’t get an error though.
var e = GetSingletonEntity<SpawnerComponent>();
var bufferEntity = GetSingletonEntity<SpawnerListComponent>();
var buffer = GetBuffer<SpawnerListComponent>(bufferEntity);
if (Input.GetKeyDown(KeyCode.Alpha1))
{
Debug.Log("You pressed to Alpha1");
EntityManager.SetComponentData(e, new SpawnerComponent { prefab = buffer[0].prefab });
}
I changed the SpawnerControlSys code like that and work like a charm.
Thank you very much.