Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411430 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 19, 2024, 05:08:47 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Actors - The component based pattern for Unity3d
Pages: [1]
Print
Author Topic: Actors - The component based pattern for Unity3d  (Read 2310 times)
pixeye
Level 1
*


You have my mace


View Profile WWW
« on: May 28, 2018, 12:17:54 AM »




ACTORS is a complete game framework with multiscene editing, game object pooling and ECS ( entity-component-system ) data-driven approach for game logic explicitly built for Unity3d. It is used to ease the pain of decoupling data from behaviors without tons of boilerplate code and without unnecessary overhead.
 
Features

- ECS events ( can be extended with Unirx )
- Very lightweight ECS syntax
- Actors ( visual entity composer in the Unity Inspector window )
- Built-in support for pooling
- Built-in support for Unity multiscene editing
- Built-in support for plugins with a pluggable wrapper that you can share with others/through projects
- Built-in support for updates through ITick, ITickFixed, ITickLate - ( faster than Unity Update methods )
- Signals ( in-memory publish/subscribe system and effectively replace Unity3d SendMessage )
- Tags ( add simple tags to entities to define states )
- Editor extensions ( foldout group in the inspector and tags editing )
- Numerous monobehavior components to help interact with the framework
- Templates for creating scriptable objects
- Game console plugin for commands and cheats
- Framework can be extended with ODIN inspector

Requirements

- Unity 2018 and higher

How to Install

From packages

- Create a new Unity Project
- Open the manifest.json file in the Packages folder inside of the Project
- Add
Code:
"com.pixeye.ecs": "https://github.com/dimmpixeye/ecs.unity.git",
- Press Tools->Actors->Update Framework[GIT] in Unity to get new update when needed

From Unity

- Download from https://github.com/dimmpixeye/ecs/releases

Documentation

* Examples
* Wiki

Simple code showcase


Code:
using UnityEngine;

namespace Pixeye
{
public class ProcessingPlayer: ProcessingBase, ITick
{

            Group<ComponentPlayer, ComponentObject> groupPlayers;
   Group<ComponentPlayer, ComponentWeapon, ComponentObject> groupPlayersWithWeapon;

public void Tick()
{
foreach (var entity in groupPlayers)
{
var cPlayer = entity.ComponentPlayer();

Debug.Log(string.Format("{0} with id {1}", cPlayer.name, entity));
}

foreach (var entity in groupPlayersWithWeapon)
{
var cPlayer = entity.ComponentPlayer();
var cWeapon = entity.ComponentWeapon();
Debug.Log(string.Format("{0} with id {1} holds {2}", cPlayer.name, entity, cWeapon.name));
}
}
}
}

« Last Edit: February 27, 2019, 02:15:01 AM by pixeye » Logged

GainDeveloper
Level 0
**


View Profile
« Reply #1 on: May 28, 2018, 08:45:03 AM »

Looks well written and organised.
Will take a better look once you have some more of the documentation written.

Great work and thanks for sharing! Smiley
Logged
pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #2 on: May 28, 2018, 10:41:34 PM »

Looks well written and organised.
Will take a better look once you have some more of the documentation written.

Great work and thanks for sharing! Smiley

Thanks, sir! : )  My Word!

I've added some documentation about Processing scripts. Basically, processings are "manager" , "controller" scripts that are used for global work or as a ECS system.

There are several predefined processings. For example ProcessingUpdate.
While Monobehavior update method can be used only with inherited mono components, you can use ProcessingUpdate with ANY script.
 
Code:
public class MyCustomClass : ITick{

 public MyCustomClass(){
   ProcessingUpdate.Default.Add(this);
 }
 
 public void Tick(){

 }

}
Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #3 on: May 30, 2018, 12:57:41 AM »

Added documentation for object pooling and timers.

Timers are delayed actions that can be used instead of simple coroutines.

Code:
Timer.Add(0.1f, actor.HandleDestroyGO); 

You can cache timers and reuse them as well.

Code:
  private Timer timerBlink;
 timerBlink = new Timer(BlinkFinish, 0.15f);
 
 void Blink(){
 timerBlink.Restart();
 }

Or add ID to manipulate with group of timers that belong to one object.

Code:
 
 Timer.Add(0.1f, actor.HandleDestroyGO).AddID(actor);
var timers = Timer.FindAllTimers(actor);

if (timers != null)
for (var i = 0; i < timers.Count; i++)
   {
timers[i].timeScale = 0.5f;
   }
Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #4 on: May 30, 2018, 11:37:21 PM »

Added descriptions for Blueprints.
Blueprints are scriptable objects for sharing common data among similar objects.

Example of pulling data from blueprint:
Code:
var weaponData = Get<DataBlueprint>().Get<DataWeapon>();

Example of blueprint:
Code:
[CreateAssetMenu(fileName = "BlueprintCreature", menuName = "Blueprints/BlueprintCreature")]
   public class BlueprintCreature : Blueprint
   {
    [FoldoutGroup("Setup")]
    public DataWeapon dataWeapon;
    
    [FoldoutGroup("Setup")]
    public DataDeathAnimations dataDeathAnimations;

    public override void Setup()
    {
     Add(dataWeapon);
     Add(dataDeathAnimations);
    }
   }
Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #5 on: June 01, 2018, 12:27:01 AM »

Added documentation for ECS approach.  
Simple ECS pattern for working with actors. My approach can be used only with actor classes at the current moment and is far less powerful than clean ECS approaches and it's used more for structuring than gaining performance boost.


Code:
public class ProcessingCameraFollow : ProcessingBase, ITick, IMustBeWipedOut{
[GroupBy(Tag.GroupPlayer)]
[GroupExclude(Tag.StateDead)]
private Group groupPlayers;

   public ProcessingCameraFollow()
   {
      groupPlayers.OnGroupChanged += OnGroupPlayersChanged;
   }

   void OnGroupPlayersChanged()
    {  
      for(var i=0;i<groupPlayers.length;i++){
         Debug.Log("Actor: " + groupPlayers.actors[i]);
      }
    }
    
   public void Tick()
   {
         for(var i=0;i<groupPlayers.length;i++){
         DoSomething(groupPlayers.actors[i]);
            }
    }
    
    void DoSomething(Actor a){
    }
    
}
« Last Edit: June 01, 2018, 01:24:48 AM by pixeye » Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #6 on: June 01, 2018, 07:25:56 AM »

After finishing documentation I'm going to make a simple game like super crate box to show framework in action : )

Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #7 on: June 01, 2018, 11:36:24 PM »

Added descriptions for tags
Tags are the glue for your game: You can identify your actors with tags or use them as arguments for your signals to check game logic. Tags are simple cont INT variables.


Code:
// Add stun marker from the mighty hammer of doom.
tags.Add(Tag.Stunned);
// Add stun marker from falling off the tree.
tags.Add(Tag.Stunned);
// remove effect caused by the mighty hammer of doom.
tags.Remove(Tag.Stunned);
// we are still stunned because we added two stun effects and removed only one
bool condition_stunned = tags.Contain(Tag.Stunned); 

Tags can be used in the Inspector window.

Code:
public static partial class Tag
    {
  [TagField(categoryName = "Weapons")] public const int WeaponGun = 9000;
  [TagField(categoryName = "Weapons/BigGuns")] public const int WeaponLaser = 9001;
    }


Code:
[TagFilter(typeof(Tag))] public int tag;



Logged

GainDeveloper
Level 0
**


View Profile
« Reply #8 on: June 04, 2018, 11:20:59 PM »

Damn! You put a lot of effort into documenting!
There's quite a lot of features strapped into this framework so I look forward to seeing the demo project to help understand how everything fits together.
Logged
pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #9 on: June 24, 2018, 08:27:26 PM »

Thanks : )  Beer!

A small but important update.  Now after saving a new scene, it will be automatically added to project build and generate unique data_yourscenename asset that you need to put inside of your starters. Also, I've added special enum helper to ease scenes navigation via code.



+ small project to show concept in action.

« Last Edit: June 24, 2018, 08:40:35 PM by pixeye » Logged

pixeye
Level 1
*


You have my mace


View Profile WWW
« Reply #10 on: February 26, 2019, 11:26:06 PM »

It's been a while since my last post : ) So I never stopped evolving the framework and a new version is ready:

Features

- ECS events ( can be extended with Unirx )
- Very lightweight ECS syntax
- Actors ( visual entity composer in the Unity Inspector window )
- Built-in support for pooling
- Built-in support for Unity multiscene editing
- Built-in support for plugins with a pluggable wrapper that you can share with others/through projects
- Built-in support for updates through ITick, ITickFixed, ITickLate - ( faster than Unity Update methods )
- Signals ( in-memory publish/subscribe system and effectively replace Unity3d SendMessage )
- Tags ( add simple tags to entities to define states )
- Editor extensions ( foldout group in the inspector and tags editing )
- Numerous monobehavior components to help interact with the framework
- Templates for creating scriptable objects
- Game console plugin for commands and cheats
- Framework can be extended with ODIN inspector

Requirements

- Unity 2018 and higher

How to Install

From packages

- Create a new Unity Project
- Open the manifest.json file in the Packages folder inside of the Project
- Add
Code:
"com.pixeye.ecs": "https://github.com/dimmpixeye/ecs.unity.git",
- Press Tools->Actors->Update Framework[GIT] in Unity to get new update when needed

From Unity

- Download from https://github.com/dimmpixeye/ecs/releases

Documentation

* Examples
* Wiki

Simple code showcase


Code:
using UnityEngine;

namespace Pixeye
{
public class ProcessingPlayer: ProcessingBase, ITick
{

            Group<ComponentPlayer, ComponentObject> groupPlayers;
   Group<ComponentPlayer, ComponentWeapon, ComponentObject> groupPlayersWithWeapon;

public void Tick()
{
foreach (var entity in groupPlayers)
{
var cPlayer = entity.ComponentPlayer();

Debug.Log(string.Format("{0} with id {1}", cPlayer.name, entity));
}

foreach (var entity in groupPlayersWithWeapon)
{
var cPlayer = entity.ComponentPlayer();
var cWeapon = entity.ComponentWeapon();
Debug.Log(string.Format("{0} with id {1} holds {2}", cPlayer.name, entity, cWeapon.name));
}
}
}
}
« Last Edit: February 26, 2019, 11:31:49 PM by pixeye » Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic