{"id":13663199,"url":"https://github.com/jeffreylanters/unity-entity-component-system","last_synced_at":"2025-10-10T20:17:59.236Z","repository":{"id":48629210,"uuid":"142878134","full_name":"jeffreylanters/unity-entity-component-system","owner":"jeffreylanters","description":"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.","archived":false,"fork":false,"pushed_at":"2023-09-06T15:03:37.000Z","size":7728,"stargazers_count":102,"open_issues_count":0,"forks_count":9,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-05-21T14:03:24.054Z","etag":null,"topics":["data-oriented","entity-component-system","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffreylanters.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"jeffreylanters"}},"created_at":"2018-07-30T13:18:27.000Z","updated_at":"2024-05-20T16:19:45.000Z","dependencies_parsed_at":"2024-01-07T04:48:28.323Z","dependency_job_id":null,"html_url":"https://github.com/jeffreylanters/unity-entity-component-system","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/jeffreylanters/unity-entity-component-system","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffreylanters%2Funity-entity-component-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffreylanters%2Funity-entity-component-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffreylanters%2Funity-entity-component-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffreylanters%2Funity-entity-component-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffreylanters","download_url":"https://codeload.github.com/jeffreylanters/unity-entity-component-system/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffreylanters%2Funity-entity-component-system/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005266,"owners_count":26083861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-oriented","entity-component-system","unity"],"created_at":"2024-08-02T05:02:20.892Z","updated_at":"2025-10-10T20:17:59.193Z","avatar_url":"https://github.com/jeffreylanters.png","language":"C#","readme":"\u003cdiv align=\"center\"\u003e\n\n![readme splash](https://raw.githubusercontent.com/jeffreylanters/unity-entity-component-system/master/.github/WIKI/repository-readme-splash.png)\n\n[![license](https://img.shields.io/badge/mit-license-red.svg?style=for-the-badge)](https://github.com/jeffreylanters/unity-entity-component-system/blob/master/LICENSE.md)\n[![openupm](https://img.shields.io/npm/v/nl.elraccoone.entity-component-system?label=UPM\u0026registry_uri=https://package.openupm.com\u0026style=for-the-badge\u0026color=232c37)](https://openupm.com/packages/nl.elraccoone.entity-component-system/)\n[![build](https://img.shields.io/badge/build-passing-brightgreen.svg?style=for-the-badge)](https://github.com/jeffreylanters/unity-entity-component-system/actions)\n[![deployment](https://img.shields.io/badge/state-success-brightgreen.svg?style=for-the-badge)](https://github.com/jeffreylanters/unity-entity-component-system/deployments)\n[![stars](https://img.shields.io/github/stars/jeffreylanters/unity-entity-component-system.svg?style=for-the-badge\u0026color=fe8523\u0026label=stargazers)](https://github.com/jeffreylanters/unity-entity-component-system/stargazers)\n[![downloads](https://img.shields.io/badge/dynamic/json?color=40AA72\u0026style=for-the-badge\u0026label=downloads\u0026query=%24.downloads\u0026url=https%3A%2F%2Fpackage.openupm.com%2Fdownloads%2Fpoint%2Fall-time%2Fnl.elraccoone.entity-component-system)](https://openupm.com/packages/nl.elraccoone.entity-component-system/)\n[![size](https://img.shields.io/github/languages/code-size/jeffreylanters/unity-entity-component-system?style=for-the-badge)](https://github.com/jeffreylanters/unity-entity-component-system/blob/master/Runtime)\n[![sponsors](https://img.shields.io/github/sponsors/jeffreylanters?color=E12C9A\u0026style=for-the-badge)](https://github.com/sponsors/jeffreylanters)\n[![donate](https://img.shields.io/badge/donate-paypal-F23150?style=for-the-badge)](https://paypal.me/jeffreylanters)\n[![awesome](https://img.shields.io/badge/listed-awesome-fc60a8.svg?style=for-the-badge)](https://github.com/jeffreylanters/awesome-unity-packages)\n\nA 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.\n\n[**Installation**](#installation) \u0026middot;\n[**Documentation**](#documentation) \u0026middot;\n[**License**](./LICENSE.md)\n\n**Made with \u0026hearts; by Jeffrey Lanters**\n\n\u003c/div\u003e\n\n# Installation\n\n### Using the Unity Package Manager\n\nInstall 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.\n\n```json\n\"nl.elraccoone.entity-component-system\": \"git+https://github.com/jeffreylanters/unity-entity-component-system\"\n```\n\n### Using OpenUPM\n\nThe 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.\n\n```sh\nopenupm add nl.elraccoone.entity-component-system\n```\n\n# Documentation\n\n## Getting Started\n\nIt'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.\n\n\u003cimg src=\"https://raw.githubusercontent.com/jeffreylanters/unity-entity-component-system/master/.github/WIKI/generator.png\" width=\"100%\"\u003e\u003c/br\u003e\n\n## Life Cycles\n\nIt's recommended to build your entire project around these life cycle methods.\n\n\u003cimg src=\"https://raw.githubusercontent.com/jeffreylanters/unity-entity-component-system/master/.github/WIKI/lifecycle.png\" width=\"100%\"\u003e\u003c/br\u003e\n\n## Controllers\n\n### Introduction\n\nThe `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 `System` and `Services` are registered. Your `Controller` should be attached to a `GameObject` in your scene and will automatically be marked to not be destroyed when switching scenes.\n\n```csharp\npublic class MainController: Controller { }\n```\n\n### Life Cycle Methods\n\n#### On Initialize Life Cycle Method\n\nThe `Controller` consists of a virtual `OnInitialize` method. This lifecycle method can be overwritten and will be invoked at the very start of your Application. During this cycle, properties with the `Injected` and `Asset` attributes are being assigned, and the `OnInitialize` method of each registered `System` and `Service` will be invoked as well.\n\n```csharp\npublic class MainController: Controller {\n  public override void OnInitialize() { }\n}\n```\n\n#### On Initialized Life Cycle Method\n\nThe `Controller` consists of a virtual `OnInitialized` method. This lifecycle method can be overwritten and will be invoked after the `OnInitialize` method has been invoked. During this cycle, the `OnInitialized` method of each registered `System` and `Service` will be invoked as well.\n\n```csharp\npublic class MainController: Controller {\n  public override void OnInitialized() { }\n}\n```\n\n#### On Update Life Cycle Method\n\nThe `Controller` consists of a virtual `OnUpdate` method. This lifecycle method can be overwritten and will be invoked every frame. During this cycle, the `OnUpdate` method of each registered `System` will be invoked as well.\n\n```csharp\npublic class MainController: Controller {\n  public override void OnUpdate() { }\n}\n```\n\n#### On Will Destroy Life Cycle Method\n\nThe `Controller` consists of a virtual `OnWillDestroy` method. This lifecycle method can be overwritten and will be invoked when the Application is about to quit. During this cycle, the `OnWillDestroy` method of each registered `System` and `Service` will be invoked as well.\n\n```csharp\npublic class MainController: Controller {\n  public override void OnWillDestroy() { }\n}\n```\n\n### Methods\n\n#### Registering Systems and Services\n\nUse this method to `Register` the Systems and Services that are required for your Application to function. The `Register` method accepts a list of `Type` arguments, each of these types should be a `System` or `Service` type.\n\nRegistering a `System` or `Service` can only be done once during the `Controller`'s `OnInitialize` life cycle method.\n\n```csharp\npublic class MainController: Controller {\n  public override void OnInitialize() {\n    Register(\n      typeof(ExampleSystem),\n      typeof(ExampleService)\n    );\n  }\n}\n```\n\n#### Disabling a System's Update Life Cycles\n\nTo enable or disable the life cycle of a `System` or `Service`, use the `SetSystemEnabled` methods. This method accepts a `Type` generic, and a `bool` value to enable or disable the life cycle of the `System` or `Service`.\n\n```csharp\npublic class MainController: Controller {\n  void SomeMethod() {\n    SetSystemEnabled\u003cExampleSystem\u003e(false);\n  }\n}\n```\n\n#### Checking whether a System's Update Life Cycles are Enabled\n\nTo check whether the life cycle of a `System` or `Service` is enabled, use the `IsSystemEnabled` methods. This method accepts a `Type` generic, and returns a `bool` value indicating whether the life cycle of the `System` or `Service` is enabled.\n\n```csharp\npublic class MainController: Controller {\n  void SomeMethod() {\n    if (IsSystemEnabled\u003cExampleSystem\u003e()) { }\n  }\n}\n```\n\n#### Manually getting a reference to a System or Service\n\nSomething you might want to get a reference to a `System` or `Service` from within something outside of the Entity Component System. To do this, use the `GetSystem`, `GetService`, `HasSystem` and `HasService` methods respectively. These methods accept a `Type` generic, or a `Type` parameter and return the `System` or `Service` instance.\n\n```csharp\npublic class MainController: Controller {\n  void SomeMethod() {\n    if (HasSystem\u003cExampleSystem\u003e()) {\n      var exampleSystem = GetSystem\u003cExampleSystem\u003e();\n      var exampleSystem = GetSystem(typeof(ExampleSystem));\n    }\n    if (HasService\u003cExampleService\u003e()) {\n      var exampleService = GetService\u003cExampleService\u003e();\n      var exampleService = GetService(typeof(ExampleService));\n    }\n  }\n}\n```\n\n#### Manually getting Assets\n\nSomething you might want to get a reference to an `Asset` from within something outside of the Entity Component System. To do this, use the `GetAsset` and `HasAsset` methods respectively. These methods accepts an optional `Type` generic and a `name` parameter and returns the `Type` or `Object`\n\n```csharp\npublic class MainController: Controller {\n  void SomeMethod() {\n    if (HasAsset\u003cExampleAsset\u003e()) {\n      var exampleAsset = GetAsset\u003cExampleAsset\u003e(\"MyAssetName\");\n      var exampleAssetObject = GetAsset(\"MyAssetName\");\n    }\n  }\n}\n```\n\n### Attributes\n\n#### Assets\n\nThe `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 its 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.\n\n```csharp\npublic class MainController: Controller {\n  [Asset] public ExampleAsset exampleAsset;\n  [Asset(\"MyAssetName\")] public ExampleAsset exampleAsset;\n}\n```\n\n#### Injection\n\nThe `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.\n\n```csharp\npublic class MainController: Controller {\n  [Injected] public ExampleSystem exampleSystem;\n  [Injected] public ExampleService exampleService;\n}\n```\n\n## Components\n\n### Introduction\n\n`Components` are responsible for storing the data of your `entities` while `Systems` are responsible for manipulating that data. `Components` are added to your `entities` (`GameObjects`) in the `Scene`, an `Entity` is not limited to one `Component` and can hold as many as needed.\n\n```csharp\npublic class MovementComponent : EntityComponent\u003cMovementComponent, MovementSystem\u003e { }\n```\n\n#### Entity Data\n\nTo provide `Systems` entity data, we'll use properties to store this. All properties should be public and will be accessible to all `Systems` and `Controllers` since there is no need for privates.\n\n```csharp\npublic class MovementComponent : EntityComponent\u003cMovementComponent, MovementSystem\u003e {\n  public float speed;\n  public Vector3 targetPosition;\n  public int[] ids;\n  public NpcDialog dialog;\n  [HideInInspector] public bool isMoving;\n}\n```\n","funding_links":["https://github.com/sponsors/jeffreylanters","https://paypal.me/jeffreylanters"],"categories":["C\\#","Code and Component Generation"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffreylanters%2Funity-entity-component-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffreylanters%2Funity-entity-component-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffreylanters%2Funity-entity-component-system/lists"}