• Stars
    star
    124
  • Rank 279,323 (Top 6 %)
  • Language
    C#
  • License
    MIT License
  • Created about 5 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

c#-Unity ECS framework

NanoECS

NanoECS - C#/Unity entity-component-system framework

Features

  • Handy and easy-to-read API
  • Reactive components (changing component values triggers collectors, giving you the ability to react to changes in ordered ecs manner)
  • Visual debugging (you can create/change contexts, entities and components inside the editor (Optional))
  • Seamless code gen (code generates on background in a standalone app, no manual actions required)
  • Unique components (singleton-like accessing components via contexts)

Showcase

The projects below made with NanoECS and Unity:

Mobile strategy Save The Earth

Save The Earth

(clickable)

Hyper Casual projects:

Hyper Race 3D Knife Away Num.io

(clickable)

First look

Entity

Create a new entity:

var player = contexts.Core.CreateEntity()	
    .AddPosition(Vector3.zero)
    .AddHealth(100)
    .AddSkin("Butterfly");

Group

Get entities with "position" and "view" components and without "movable" component:

CoreGroup group = contexts.Core.GetGroup()
    .With.Position
    .With.View
    .Without.Movable;

Usage:

Handle filtered entities:

foreach (e in group) 
{	
	Print(e.Position.Value);
	Print(e.View.Value);
	Print(e.View.IsMovable);
}

Collector

Get all entities with "Speed" and "Position" only when the position value is changed:

CoreCollector collector = contexts.Core.GetGroup()
    .With.Speed
    .With.Position
    .OnPositionChange();

Handle these entities:

foreach (e in collector) 
{	
	Print("My position has changed! : {0}", e.Position.Value);
}
collector.Clear();

Accessing component values

example 1:

e.Position.Value += e.Direction.Value.ToVector3() * e.Speed.Value * delta;

example 2:

foreach (var player in defeatedPlayers)
{
    player.IsDestroyed = true;
    player.DefeatsCounter.Value++;

    if (!player.IsAIDriven)
    {
	contexts.Request.CreateEntity()
	    .AddDelay(0.6f)
	    .IsGameOverRequest = true;
    }
}

Visual Debugging

  • Reactive editing support (modifiyng component values)

entity editor

  • Natural auto-complete workflow for adding new components, Foldouts, Create/Destroy buttons

entity editor

  • GameObject linking (jump from the entity to the view game object and vice versa)
  • Lists, custom types, enums, Unity Objects are supported
  • Doesn't affect realease builds performance. (And can be disabled / enabled manually in the settings)

Code Generation

entity editor

  • Generation works without reflection, so you can generate even if your project doesn't compile at all
  • Doesn't requere any manual actions from user to trigger generation. Just write the code and see how the new API appears. (Optional)
  • Customizable generation snippets.

How to use generator?

  • Go to Packages -> NanoECS -> Generator and run NanoEcsGenerator
  • Insure that you have a folder named Components somewhere inside your Assets folder
  • Create new component there, for example:
class Score
{
    int value;
}

Generator will automatically detect changes and create API fow you. You dont need to leave your IDE, just keep writing your code.

A few tips:

  • yes, you dont need to write "public" access modifier. It's just a "blueprint" for a real component.
  • use camelCase for fields (real property will be PascalCased)
  • Fieldless components (e.g. class Movable { }) looks this way in the result: entity.IsMovable = true
  • you can use namespaces
  • you can use different contexts by adding a corresponding attribute(s). If you don't specify any context at all, the first one from NanoECS settings will be chosen.
  • if you prefer performance over convicience, you could disable default reactive behavior for component accessors by untiping the toggle in NanoEcs Settings. (But you still able to selectivly use it by applying [Reactive] attribute above your component.
  • if use want to extend generation behavior, you can change code snippets.

NanoEcs Generator sources

If you for some reasons want to edit NanoEcs generator, the sources are available here.

Inspiration and goals

The framework is inspired a lot by such projects as Entitas, Actors, LeoECS.

But I found that Entitas has some design problems to me:

  • need of writing Replace() methods every time you want to change a component value and make sure reactive system "know" about it.
  • Filter validation along with Matcher is redundant. User is forced to write both of them to make sure components are still there.
  • Matcher declaration has a lot of boilerplate.

The goal of this project was to make API as much fluent as possible, and keep performance as well.

Documentation

Wiki

How to install

  • Create a new Unity Project
  • Open the manifest.json file in the Packages folder inside of the Project
  • Add "com.nanory.nanoecs": "https://github.com/SinyavtsevIlya/NanoECS.git", next to "dependencies": {
  • Go to Packages -> NanoECS -> Install and import ProjectStructure.unitypackage

Should I use it?

Before making a decision, pay attention to a few points:

  • if you want super performance, just take DOTS.
  • support and bug fixes are active
  • new features are not planned

Feedback

If you find a bug, have some suggestions or just want to discuss, let me know: