前言:我是被守望先鋒和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目錄下。如圖所示:
3.滑鼠右鍵點選Unity的Assets目錄并在展開操作清單中點選Open C# Project,這樣目的是生成項目程式集。如圖所示:
4.選擇Tools->Jenny->Preferences->Auto Import來擷取代碼生成器所需的工程配置資訊。如下圖所示:
自動導入時,代碼生成器會重寫配置資訊,這裡選擇Continue and Overwrite就行。如圖所示:
5.在代碼生成器中選擇Generate(shift + ctrl + g)來導出Entitas工程代碼。如圖所示:
Hello World編寫:這裡我采用預設的代碼導出配置。如圖所示導出Entitas環境。
編寫流程如下:
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檔案。如圖所示:
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實體的列印資訊。如圖所示:
調試工具簡介:基本描述如下圖所示: