ECS框架学习(Entitas)入门

公司要求使用ECS框架经行开发,没办法只能自己学习了。记录一下学习过程。

框架的含义可以去其他地方查看,我这里写一点我的理解(新人,不对请谅解)。ECS即Entity-Component-System(实体-组件-系统) 的缩写。它做到了行为、数据分开,Component存数据。Entity用来就是由各个Component组成。System用来经行他们中间的通信。对于网上或者官方说速度更快、更容易重构代码的说法我都没有体验到,新人,算了经行讲解吧。

版本:unity5.6.6f2(2018.x中已集成该插件直接倒入,理论上也可以按我的方法实现,没试过)

        Entitas1.13

官方HelloWorld案例:https://github.com/sschmid/Entitas-CSharp/wiki/Unity-Tutorial-Hello-World

插件下载地址:https://github.com/sschmid/Entitas-CSharp/releases

下载ENtitas.zip解压,有两个文件夹DesperateDevs和Entitas倒入unity中,会多一个Tools菜单选项,点击Preferences或快捷键Ctrl+Shift+J会出现框架配置界面。

ECS框架学习(Entitas)入门_第1张图片ECS框架学习(Entitas)入门_第2张图片

点击AutoImport经行一下默认配置,ProjectPath填写自己工程名字+.csproj(我自己填写的ECS_MoveDemo.csproj),Contextsz中需要序列化的关键字,默认有Game和Input。对于一些有自己需要的序列化可以在这里添加。点击Generate经行配置。ECS框架学习(Entitas)入门_第3张图片

成功过后会多一个Generated的文件夹。

Hellowworld案例:

1、创建一个数据脚本DebugMessageComponent.cs

using Entitas;

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

2、创建一个系统DebugMessageSystem.cs用来监听message的值,我的理解类似事件吧

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

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

    protected override ICollector GetTrigger(IContext context)
    {
        return context.CreateCollector(GameMatcher.DebugMessage);
    }

    protected override bool Filter(GameEntity entity)
    {
        return entity.hasDebugMessage;
    }

    protected override void Execute(List entities)
    {
        foreach (var e in entities)
        { 
            Debug.Log(e.debugMessage.message);
        }
    }
}

3、创建赋值初始化系统HelloWorldSystem.cs,恩恩恩,就是现在还需要一个赋值操作,毕竟message现在是null

using Entitas;

public class HelloWorldSystem : IInitializeSystem
{ 
    readonly GameContext _context;

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

    public void Initialize()
    {
        _context.CreateEntity().AddDebugMessage("Hello World!");
    }
}

4、同时我们还想让他监听鼠标按下,所以创建LogMouseClickSystem.cs,理解的话也是赋值操作

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、在鼠标点击时,每一次都会创建一个实体,我们需要销毁它经行第一步的优化,创建CleanupDebugMessageSystem.cs

using Entitas;

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

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

    public void Cleanup()
    {
        foreach (var e in _debugMessages.GetEntities())
        {
           e.Destroy();
        }
    }
}

6、现在各个功能都实现了,我们需要创建这些类的实例即这个类的对象,所以创建TutorialSystems.cs

 

using Entitas;

public class TutorialSystems : Feature
{
    public TutorialSystems(Contexts contexts) : base ("Tutorial Systems")
    {
        Add(new HelloWorldSystem(contexts));
        Add(new LogMouseClickSystem(contexts));
        Add(new DebugMessageSystem(contexts));
        Add(new CleanupDebugMessageSystem(contexts)); 
    }
}

7、这时我们大部分功能都完成了,需要和Unity经行关联起来创建GameController.cs

using Entitas;
using UnityEngine;

public class GameController : MonoBehaviour
{
    Systems _systems;

    void Start()
    {
        var contexts = Contexts.sharedInstance;
        _systems = new Feature("Systems").Add(new TutorialSystems(contexts));
        _systems.Initialize();
    }

    void Update()
    {
        _systems.Execute();
        _systems.Cleanup();
    }
}

8、终于完成了这个过程,在unity创建一个空物体,将GameController.cs组件添加到这个空物体运行就可以看到效果了

下边是我对Entitas中的类理解。

IInitializeSystem  在开始前执行一次system.Initialize()。通常初始化时经行数据的赋值。类似Start()

IExecuteSystem  执行每一帧system.Execute()。常用来执行每帧改变数据。类似Update()

ICleanupSystem   在其他系统完成后执行每一帧system.Cleanup()通常执行销毁实体功能。类似LeteUpdate()

ITearDownSystem结束后执行一次system.TearDown()。类似OnDestroy()

ReactiveSystem观察到的组发生变化时执行system.Execute(Entity[])创建一个构造函数,该构造函数调用基础构造函数并为其提供适当的上下文。重写3个方法:GetTrigger()返回一个收集器,它告诉系统要响应的事件。Filter()对收集器返回的实体进行最终检查,确保在Execute()调用每个实体之前附加了所需的组件。Execute()是大部分游戏逻辑所在的位置。在重写Execute()方法时,它会对数据进行监听,对应的数据改变时,它会执行Execute()中的功能。

你可能感兴趣的:(ECS框架学习(Entitas)入门)