Just starting on ECS and had a Questions (Please let me know if im on the wrong forum)
So I have a tile based game. Im trying to build the board using ECS. Ive started by setting up my components, entities and now the build system.
This is where im confused, i only see a OnUpdate() function. How do I control the execution of this function.I only need to build my hex tiles once ( populate 2 component arrays) how do I break out of this system or decide when to run the system.
namespace Test.HexSphereECS
{
/// <summary>
/// System for creating a hexSphere
/// </summary>
public class HexSphereBuildSystem : ComponentSystem
{
// Must implement for ComponentSystem
protected override void OnUpdate()
{
// Build my Sphere
}
}
}
You have OnCreateManager/OnDestroyManager as virtual methods you can override. Those are where you should do your setup/teardown, allocation/dispose persistent native containers, etc… Like below. OnDestroyManager same pattern.
Such array is unnecessary. Actually, it’s against ECS principles. You should add a common component to these entities and use EntityQuery to get all the chunks with your component. ArchetypeChunk has GetNativeArray function. It returns NativeArray of entities from the chunk. You can access it from different systems. This approach is better because:
You don’t need a static array of entities (it’s bad design anyway)
You have more efficient access to component data (linear memory block per chunk, and you don’t have to ask for data of every entity in your array)
Entity array is always up to date. Added/removed component will be immediately updated, and all other systems will get updated NativeArrays form queries.
It’s also easier to introduce multithreading without static arrays with global access. Job system has great race condition detection and automatic dependency tracking. You should stick to the ECS principles and soon everything will be way easier.
Got it thanks heaps for the help, Ok given what I think I understood I jumped the gun here, Im not even up to the point of accessing the entities. So what im trying to refactor into ECS is a hexSphere sudivision from an Icosahedron. So I need to create the base Icosahedron first and then access those components using EntityQuery ( Like everything in ESC first time ive heard of it)
Here is what I came up with, any critiques would be appreciated.
My questions
I noticed that Im required to implement OnUpdate() but im not using it, seems like something is wrong.
Is the BootstrapECS class needed ? Only thing im doing here is defining an EntityArchetype. Is this the correct place to do it in this design pattern ?
namespace TEST.HexSphereECS
{
/// <summary>
/// HexTile - A Hextile is a single hex (or sometimes pentagon)
/// in the hex tiled planet. It is a single vertex of the mesh
/// </summary>
public struct HexVertexComponent : IComponentData
{
#region FLIELDS --------------------------------------------------------
public int hexIndex;
public float3 position;
public int connectedTriA; //Index into the HexTri array that share this hex
public int connectedTriB; //Index into the HexTri array that share this hex
public int connectedTriC; //Index into the HexTri array that share this hex
public int connectedTriD; //Index into the HexTri array that share this hex
public int connectedTriE; //Index into the HexTri array that share this hex
public int connectedTriF; //Index into the HexTri array that share this hex
#endregion
}
}
ComponentSystem already has an accessor for EntityManager so no need to create a reference for it in HexSphereBuildSystem.
I’m not sure myself where is the best place to bootstrap stuff but what you’re doing looks fine. If you’re spawning entities as part of level creation, it might be best to put it all in a single level bootstrap system but if they’re related to the functioning of a specific system, then individual systems might be the best place.
E.g. a TimerSystem that ticks time might itself create the singleton Timer entity that it operates on.
OnUpdate is where you process the queries for a system.
As an example.
OnUpdate(){
Entities.ForEach<HexVertexComponent>( (ref HexVertexComponent hexVertex) => {
// Do something with hexVertex;
});
}
The idea being that a system performs an operation(s) on a set of entities that match a query.
The system knows what queries have been registered with it (HexVertexComponent in the above eg) and OnUpdate() won’t run if there are no entities that match the query.
You can also explicitly create queries like so which you need sometimes if using multiple queries or chunk iteration or jobs: