About entity component system design

Started by
1 comment, last by Madhed 9 years, 11 months ago
Hi, everyone~
I'm developing a third-person shooter game with the Unity Engine(C#).
After read some articles about the entity component system(ECS)[1][2][3][4], I decided to use the ECS pattern for my game.
The sample code below shows my first design.

    player {
      // components(pure data)
      input;
      movement;
      position;
      health;

      // system
      humanAnimatorController {input, movement}
      humanMovementController {input, movement}
      humanAttackController {input}
      humanUserInput {input}
    }

    zombie {
      // components(pure data)
      input;
      movement;
      position;
      health;

      // system
      zombieAnimatorController {input, movement}
      zombieMovementController {input, movement}
      zombieAttackController {input}
      zombieAIInput {input}
    }

Everything seems fine until I decided to add some unique actions to a zombie, like bite, eat, crawl...
The problem is, the input component doesn't contain such input data(bite, eat, crawl...) that the zombieAttackController needs.
Below is some of my thoughts, but I'm still not sure how to do it.
1. Make the input component contain all the possible data, e.g.

    input {
      Vector3 move;
      bool action_bite,
      bool action_eat,
      bool action_crawl,
      ...
    }
   
    // Or this way

    input {
      map<string, object> input_data;
    }

2. Make another component for zombie input, like zombieInput

    zombie {
      // components(pure data)
      input;
      zombieInput; // new component for zombie, contain special inputs like bite, eat, crawl...
      movement;
      position;
      health;

      // system
      zombieAnimatorController {input, zombieInput, movement}
      zombieMovementController {input, zombieInput, movement}
      zombieAttackController {input, zombieInput}
      zombieAIInput {input, zombieInput}
    }
This may add too many components to the system, there might be ninjaInput, robotInput, rifleInput, tankInput, which also decrease the reusablity of my code.

3. Traditional OOP solution or some other solutions.
Advertisement

hmm - well im not sure about having your systems contained in each entity - I use systems that are classes themselves derived from a System base class and stored as a vector of systems within the engine - each frame every system in the vector is updated once per frame

Each system is also given a pointer to the scene data and only operates on certain components of each entity - you can also do this (which is perhaps more common) by passing each system a list of components they will operate on each frame (a list of indexes or pointers that is), or you can pass them a list of entities and let each system determine the components of each entity they will operate on

In your case that would mean having AnimatorController, MovementController, AttackController, and AIInput as systems for the engine, and letting them determine which entities/components they should operate on in their update functions

But this is just how I have seen this done most times - I wouldn't call myself a know all expert here

As far as your components go - again using inheritance in the component system is not a bad thing in my opinion - so that if you want to make input components for lots of different things you can make one base input component class with some set of functions that could be redefined for specific types of other input components..

But it is normal to have lots of components - and components that are specific to your game and not "re-usable".. this is because components are where you really define your game objects.. in the classic approach you had entire classes defining game objects and in ent/comp you have a lot of components that define your objects - some components will be re-usable for many of your objects (like health component for example, or maybe attack component) but some components will be very specific to certain objects

Wait. You're using Unity right? Unity itself already contains an ECS.

Components are subclasses of Unity's MonoBehaviour class.

Entities are instances of Unity's Entity class.

Systems don't really exist in Unity because it uses the kind of entity system where components also contain logic.

To me it seems kind of "wrong" to implement your own ECS on top of that.

This topic is closed to new replies.

Advertisement