天天看點

Entitas深入研究(1):環境安裝和HelloWorld

前言:我是被守望先鋒和unity推出的ecs程式設計模式給騙進來的。

Entitas簡介:Entitas是專門用于Unity引擎的一款超快速、輕量級實體元件系統(ECS)。它經過了精心設計,不僅可以快速通路元件,也可以在垃圾收集環境中以最佳方式工作。

Entitas基本概念:

1.Entity表示一個實體,用來存儲資料用的。

2.Context表示上下文環境,用來建立和銷毀Entity用的。

3.Group表示組,用來将相同類型的Entity歸納到一起用的。

4.Matcher表示比對查找,用來從Context中擷取感興趣的Group。

5.Collector表示采集,用來從Group中收集變化的Entity。

6.System表示系統,用來處理邏輯的。通常存在五種類型,分别如下:

->.IInitializeSystem隻在初始化時調用一次。初始化實作可以寫在Initialize方法中。

->.IExecuteSystem會在每幀執行一次。執行邏輯可以寫在Execute方法中。

->.ICleanupSystem會在别的System完成後,每幀執行一次。回收邏輯可以寫在Cleanup方法中。

->.ReactiveSystem會在Group有變化時執行一次。執行邏輯可以寫在Execute方法中。

->Feature會将上述的System進行整合以及建立。

Entitas安裝:安裝流程如下:

1.下載下傳Entitas,這裡我下載下傳的是目前最新的1.12.2版本。

2.建立一個空的Unity工程項目,并建立一個Libraries目錄。然後将下載下傳好的Entitas.zip解壓并将Assets目錄下的Entitas和DesperateDevs複制到Libraries目錄下。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

3.滑鼠右鍵點選Unity的Assets目錄并在展開操作清單中點選Open C# Project,這樣目的是生成項目程式集。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

4.選擇Tools->Jenny->Preferences->Auto Import來擷取代碼生成器所需的工程配置資訊。如下圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

自動導入時,代碼生成器會重寫配置資訊,這裡選擇Continue and Overwrite就行。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

5.在代碼生成器中選擇Generate(shift + ctrl + g)來導出Entitas工程代碼。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

Hello World編寫:這裡我采用預設的代碼導出配置。如圖所示導出Entitas環境。

Entitas深入研究(1):環境安裝和HelloWorld

編寫流程如下:

1.在Assets目錄下建立一個Sources/Components目錄,并添加一個DebugMessageComponent.cs檔案。這個檔案就是包含一個記錄日志資訊的成員變量。檔案内容如下:

using Entitas;

[Game]
public class DebugMessageComponent : IComponent 
{    
    public string message;
}
           

然後使用Tools->Jenny->Generate或者ctrl + shift + g在Generated/Game中建立Components目錄并建立一個GameDebugMessageComponent.cs檔案。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

2.在Assets目錄下建立一個Sources/Systems目錄,并添加一個DebugMessageSystem.cs檔案。這個檔案就是對DebugMessageComponent實體的變化進行收集,并在執行接口裡面進行列印日志資訊。檔案内容如下:

using System.Collections.Generic;
using Entitas;
using UnityEngine;

public class DebugMessageSystem : ReactiveSystem<GameEntity>
{
    public DebugMessageSystem(Contexts contexts) : base(contexts.game)
    {
    }

    protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
    {
        // we only care about entities with DebugMessageComponent 
        return context.CreateCollector(GameMatcher.DebugMessage);
    }

    protected override bool Filter(GameEntity entity)
    {
        // good practice to perform a final check in case 
        // the entity has been altered in a different system.
        return entity.hasDebugMessage;
    }

    protected override void Execute(List<GameEntity> entities)
    {
        // this is the list of entities that meet our conditions
        foreach (var e in entities)
        { 
            // we can safely access their DebugMessage component
            // then grab the string data and print it
            Debug.Log(e.debugMessage.message);
        }
    }
}
           

3.在System目錄下添加一個HelloWorldSystem.cs檔案。這個檔案會在初始化接口調用時建立一個DebugMessageComponent實體對象。檔案内容如下:

using Entitas;

public class HelloWorldSystem : IInitializeSystem
{ 
    // always handy to keep a reference to the context 
    // we're going to be interacting with it
    readonly GameContext _context;

    public HelloWorldSystem(Contexts contexts)
    { 
        // get the context from the constructor
        _context = contexts.game;
    }

    public void Initialize()
    {
        // create an entity and give it a DebugMessageComponent with
        // the text "Hello World!" as its data
        _context.CreateEntity().AddDebugMessage("Hello World!");
    }
}
           

4.在Systems目錄下添加一個LogMouseClickSystem.cs檔案。這個檔案會對滑鼠左右鍵進行監聽。一旦滑鼠左右鍵觸發就會建立一個DebugMessageComponent實體對象。檔案内容如下:

using Entitas;
using UnityEngine;

public class LogMouseClickSystem : IExecuteSystem
{
    readonly GameContext _context;

    public LogMouseClickSystem(Contexts contexts)
    {
        _context = contexts.game;
    }

    public void Execute()
    {
        if (Input.GetMouseButtonDown(0))
        {
            _context.CreateEntity().AddDebugMessage("Left Mouse Button Clicked");
        }

        if (Input.GetMouseButtonDown(1))
        {
            _context.CreateEntity().AddDebugMessage("Right Mouse Button Clicked");
        }
    }
}
           

5.在Systems目錄下添加一個CleanupDebugMessageSystem.cs檔案。這個檔案會對DebugMessageComponent實體進行收集,并在回收接口調用時回收掉收集的實體。檔案内容如下:

using Entitas;

public class CleanupDebugMessageSystem : ICleanupSystem
{
    readonly GameContext _context;
    readonly IGroup<GameEntity> _debugMessages;

    public CleanupDebugMessageSystem(Contexts contexts)
    {
        _context = contexts.game;
        _debugMessages = _context.GetGroup(GameMatcher.DebugMessage);
    }

    public void Cleanup()
    {
        // group.GetEntities() always gives us an up to date list
        foreach (var e in _debugMessages.GetEntities())
        {
           e.Destroy();
        }
    }
}
           

6.在Systems目錄中添加一個HelloWorldFeature.cs檔案。這個檔案主要是按照順序将各個System添加進來。檔案内容如下:

using Entitas;

public class HelloWorldFeature : Feature
{
    public HelloWorldFeature(Contexts contexts) : base ("Tutorial Systems")
    {
        Add(new HelloWorldSystem(contexts));
        Add(new LogMouseClickSystem(contexts)); // new system
        Add(new DebugMessageSystem(contexts));
        Add(new CleanupDebugMessageSystem(contexts)); // new system (we want this to run last)
    }
}
           

7.在Sources目錄下建立一個遊戲入口GameController.cs檔案。這個檔案主要是建立全局Context并建構HelloWorldFeature對象。檔案内容如下:

using Entitas;
using UnityEngine;

public class GameController : MonoBehaviour
{
    Systems _systems;

    void Start()
    {
        // get a reference to the contexts
        var contexts = Contexts.sharedInstance;
        
        // create the systems by creating individual features
        _systems = new Feature("Systems")
            .Add(new HelloWorldFeature(contexts));

        // call Initialize() on all of the IInitializeSystems
        _systems.Initialize();
    }

    void Update()
    {
        // call Execute() on all the IExecuteSystems and 
        // ReactiveSystems that were triggered last frame
        _systems.Execute();
        // call cleanup() on all the ICleanupSystems
        _systems.Cleanup();
    }
}
           

8.在場景中建立一個空的對象GameController,并綁定好上面建立的GameController.cs遊戲入口檔案。然後點選運作,以及滑鼠左右點選,便可以看見DebugMessageComponent實體的列印資訊。如圖所示:

Entitas深入研究(1):環境安裝和HelloWorld

調試工具簡介:基本描述如下圖所示:

Entitas深入研究(1):環境安裝和HelloWorld
Entitas深入研究(1):環境安裝和HelloWorld