unity-entity-component-system icon indicating copy to clipboard operation
unity-entity-component-system copied to clipboard

A better approach to game design that allows you to concentrate on the actual problems you are solving: the data and behavior that make up your game. By moving from object-oriented to data-oriented de...

readme splash

license openupm build deployment stars awesome size sponsors donate

A better approach to game design that allows you to concentrate on the actual problems you are solving: the data and behavior that make up your game. By moving from object-oriented to data-oriented design it will be easier for you to reuse the code and easier for others to understand and work on it.

Installation · Documentation · License

Made with ♥ by Jeffrey Lanters

Installation

Using the Unity Package Manager

Install the latest stable release using the Unity Package Manager by adding the following line to your manifest.json file located within your project's Packages directory, or by adding the Git URL to the Package Manager Window inside of Unity.

"nl.elraccoone.entity-component-system": "git+https://github.com/jeffreylanters/unity-entity-component-system"

Using OpenUPM

The module is availble on the OpenUPM package registry, you can install the latest stable release using the OpenUPM Package manager's Command Line Tool using the following command.

openupm add nl.elraccoone.entity-component-system

Documentation

Getting Started

It's recommended to get started by using the built-in File Generator. When it's your first time using the ECS, you might want to enable the Overwrite All Virtuals option to see all the available methods for each type of class.

Life Cycles

It's recommended to build your entire project around these life cycle methods.

Controllers

Introduction

The Controller is the heart of your Application, each Application should consist of just one, commonly named the MainController. The Controller is the first entry point of the Entity Component System and is the place where all of your Systems and Services are registered. Your Controller should be attached to a Game Object in your scene and will be marked to not be destroyed when switching scenes.

public class MainController : Controller { }

Virtual On Initialize

The Controller consists of an OnInitialize virtual method. This method can be overwritten and will be invoked during the very start of your Application. During this cycle properties with the Injected and Asset attribute are being assigned, it is important to invoke the Register method during this cycle since this is the only time in your Application you can register Systems and Services.

public class MainController : Controller {
  public override void OnInitialize () {
    this.Register (
      typeof (MovementSystem),
      typeof (AudioService)
    );
  }
}

Virtual On Initialized

The Controller consists of an OnInitialized virtual method. This method can be overwritten and will be invoked when all Systems and Services did initialize, and all the properties with the Injected and Asset attributes are assigned.

public class MainController : Controller {
  public override void OnInitialized () { }
}

Virtual On Update

The Controller consists of an OnUpdate virtual method. This method can be overwritten and will be invoked during the Update cycle. This cycle will run once every frame, the Controller's Update is invoked before the System's and Service's update cycles.

public class MainController : Controller {
  public override void OnUpdate () { }
}

Enabling Systems

To enable or disable Systems, the Controller contains of a method EnableSystem which allows Systems to stop their life cycle methods such as OnUpdate, OnPhysics, OnDrawGui and others. You can provide the System's type using a generic. Systems are enabled by default.

public class MainController : Controller {
  public void SomeMethod () {
    this.SetSystemEnabled<MovementSystem> (true);
    this.SetSystemEnabled<InteractableSystem> (false);
  }
}

Checking Whether Systems Are Enabled

To check whether Systems are enable or disabled, the Controller contains of a method IsSystemEnabled. Invoking the method will return a boolean informing if the System is enabled or not. You can provide the System's type using a generic.

public class MainController : Controller {
  public void SomeMethod () {
    if (this.IsSystemEnabled<MovementSystem> ()) { }
  }
}

Injection

The Controller allows the use of the Injected attribute on properties to automatically assign the values of referenced Systems and Services, making all public methods and properties accessible. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle.

public class MainController : Controller {
  [Injected] private MovementSystem movementSystem;
  [Injected] private AudioService audioService;
}

Assets

The Controller allows the use of the Asset attribute on properties to automatically assign the values of referenced Assets. Assets can be assigned on the Controller instance in your Scene. When assigning using the empty contructor, the property's name will be used for searching the Asset, to find an Asset by it's name, use the string overload. All types of UnityEngine's Object can be used in these fields. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle. When an asset is not found, an error is thrown.

public class MainController : Controller {
  [Asset] private GameObject playerPrefab;
  [Asset ("ShopDialog")] private NpcDialog npcDialog;
}

Notes

While it is recommended to move as much logic into Services and Systems, it is possible to let your Controller house any functionality. If you use the Controller for this purpose, try to keep it down to only Application wide and core functionality.

Components

Introduction

Components are responsible for housing the data of your entities, and should consist of nothing more than that. All properties should be public and will be accessible to all Systems and Controllers since there is no need for privates. Components should be added to your Entities (GameObjects) in the Scene, an Entity is not limited to one Components and can hold as many as needed.

public class MovementComponent : EntityComponent<MovementComponent, MovementSystem> { }

Public Properties

Public properties are the heart of your Components, and are here to provide data for the Systems to use. Properties can be added to Components like in any other class and can consist of any kind of type.

public class MovementComponent : EntityComponent<MovementComponent, MovementSystem> {
  public float speed;
  public Vector3 targetPosition;
  public int[] ids;
  public NpcDialog dialog;
}

Editor Protection

Sometimes you want to hide properties from the Unity Editor when they are, for example are managed by the Systems. By flagging these properties with the Protected attribute, it will no longer shows up in the Unity Editor, but is still accessible by the Systems.

public class MovementComponent : EntityComponent<MovementComponent, MovementSystem> {
  [Protected] public float currentSpeed;
}

## Systems

### Introduction

The [Systems](#systems) are responsible for controlling all of your Entity's [Components](#components) and are the closest you'll get of what you're used to when working with MonoBehaviours. The entire life cycles of your Entities are managed in here.

```csharp
public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> { }

Virtual On Initialize

The System consists of an OnInitialize virtual method. This method can be overwritten and will be invoked during the very start of your Application. During this cycle properties with the Injected and Asset attribute are being assigned. This cycle can be used to create instances or pre-set properties. Keep in mind references to other System and Services are yet to be assigned and are not available at this point.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  public override void OnInitialize () { }
}

Virtual On Initialized

The System consists of an OnInitialized virtual method. This method can be overwritten and will be invoked when all System and Services did initialize, and all the properties with the Injected and Asset attributes are assigned.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  public override void OnInitialized () { }
}

Virtual On Enabled

The System consists of an OnEnabled virtual method. This method can be overwritten and will be invoked when all System and Services are initialized or when the System is enabled after being disabled.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  public override void OnEnabled () { }
}

Checking wether an Entity is enabled

To check whether Entities are enable or disabled, the Component consists of a property isEnabled. Getting the value will return a boolean informing if the Entity is enabled or not.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  private void SomeMethod () {
    if (this.entity.isEnabled == true) { }
  }
}

Dependency Injection

The System allows the use of the Injected attribute on properties to automatically assign the values of referenced Systems, Services and Controllers, making all public methods and properties accessible. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  [Injected] private MainController mainController;
  [Injected] private HealthSystem healthSystem;
  [Injected] private AudioService audioService;
}

Assets

The System allows the use of the Asset attribute on properties to automatically assign the values of referenced Assets. Assets can be assigned on the Controller instance in your Scene. When assigning using the empty contructor, the property's name will be used for searching the Asset, to find an Asset by it's name, use the string overload. All types of UnityEngine's Object can be used in these fields. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle. When an asset is not found, an error is thrown.

public class MovementSystem : EntitySystem<MovementSystem, MovementComponent> {
  [Asset] private GameObject playerPrefab;
  [Asset ("ShopDialog")] private NpcDialog npcDialog;
}

The systems section of the documentation is in process!

Services

Introduction

public class AudioService : Service<AudioService> { }

Dependency Injection

The Service allows the use of the Injected attribute on properties to automatically assign the values of referenced Systems, Services and Controllers, making all public methods and properties accessible. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle.

public class AudioService : Service<AudioService> {
  [Injected] private MainController mainController;
  [Injected] private MovementSystem movementSystem;
  [Injected] private NetworkService networkService;
}

Assets

The Service allows the use of the Asset attribute on properties to automatically assign the values of referenced Assets. Assets can be assigned on the Controller instance in your Scene. When assigning using the empty contructor, the property's name will be used for searching the Asset, to find an Asset by it's name, use the string overload. All types of UnityEngine's Object can be used in these fields. These properties are assigned during the OnInitialize cycle and are available for use at the OnInitialized cycle. When an asset is not found, an error is thrown.

public class AudioService : Service<AudioService> {
  [Asset] private GameObject playerPrefab;
  [Asset ("ShopDialog")] private NpcDialog npcDialog;
}

The services section of the documentation is in process!