ntityComponentSystem 架构Entitas 初步理解(一)
我们紧接着写第二篇,第一篇是对Entitas的初步理解
这里可以改代码的生成路径
1.打印Helloworld
- 新建文件夹Components新建脚本LogComponent, 继承IComponent接口, 引入命名空间 using Entitas;
上节课我们说过 Component是数据的载体。
其实就是---数据
- 新建文件夹Systems 新建脚本LogSystem 继承 RecaveSystem<GameEntity>类, 引入命名空间 using Entitas;
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 打印消息 组件 需要添加一些特殊的标签 来说明这个类是干嘛的
/// log是数据Game下面的 一共预定义两个,一个是Game 游戏,Input 输入 标签
/// 现在使用的是Game标签
/// </summary>
[Game]
public class LogComponent : IComponent {
/// <summary>
/// 打印信息
/// </summary>
public string message;
}
其实是---用来处理数据的逻辑部分
- LogSystem 继承 RecaveSystem<GameEntity> 重写一下构造方法里面是可以传 下面两个
第一个是获取上下文??
解释:但是教程里面为啥传这个不是很懂??
GameContext是继承自 Context<GameEntity>
Context<GameEntity> 继承自Context<TEntity>
Context<TEntity> 继承自IContext<TEntity>
所以contexts.game的返回值是 GameContext 所以 用下面的就行
- 然后这时候点击生成代码生成代码后
生成代码后 就会吧LogComponent类所对应生成一系列的类,比方说保护这个实体是否含有这个组件,是否包含 当前属性
- LogSystem 类中的:
1,Filter 方法相当于一个过滤器 生成代码以后 。Filter 方法return entity.hasLog;
也就是说 如果 不包含haslog的话,就不会往下执行
2, GetTrigger(触发器 方法) 创建一个收集器 return context.CreateCollector( ); 他会对group操作进行相应 需要传入一个匹配的参数GameMatcher.Log 主要对于所有实体的变化的一个数组进行相应 。。
多些几个就知道了 如果是Log的话 就要GameMatcher.Log 如果是Position GameMatcher.Position。,
3,Execute 方法 满足条件后 执行相应的逻辑
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 打印消息系统
/// </summary>
public class LogSystem : ReactiveSystem<GameEntity>
{
public LogSystem(Contexts contexts) : base(contexts.game)
{
}
/// <summary>
/// 过滤器 代表执行条件
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
protected override bool Filter(GameEntity entity)
{
return entity.hasLog;
}
/// <summary>
/// 触发器
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
//创建一个收集器??他会对group操作进行相应 需要传入一个匹配的参数GameMatcher.Log 主要对于所有实体的变化的一个数组进行相应
//多写几个就知道了 如果是Log的话 就要GameMatcher.Log 如果是Position GameMatcher.Position
return context.CreateCollector(GameMatcher.Log);
}
/// <summary>
/// 满足条件后 执行相应的逻辑
/// </summary>
/// <param name="entities"></param>
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entity in entities)
{
Debug.LogFormat("打印的消息为【{0}】", entity.log.message);
}
}
}
- 修改这两个类 添加命名空间 Helloworld
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HelloWorld
{
/// <summary>
/// 打印消息 组件 需要添加一些特殊的标签 来说明这个类是干嘛的
/// log是数据Game下面的 一共预定义两个,一个是Game 游戏,Input 输入 标签
/// 现在使用的是Game标签
/// </summary>
[Game]
public class LogComponent : IComponent
{
/// <summary>
/// 打印信息
/// </summary>
public string message;
}
}
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HelloWorld
{
/// <summary>
/// 打印消息系统
/// </summary>
public class LogSystem : ReactiveSystem<GameEntity>
{
public LogSystem(Contexts contexts) : base(contexts.game)
{
}
/// <summary>
/// 过滤器 代表执行条件
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
protected override bool Filter(GameEntity entity)
{
return entity.hasHelloWorldLog;
}
/// <summary>
/// 触发器
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
//创建一个收集器??他会对group操作进行相应 需要传入一个匹配的参数GameMatcher.Log 主要对于所有实体的变化的一个数组进行相应
//多写几个就知道了 如果是Log的话 就要GameMatcher.Log 如果是Position GameMatcher.Position
return context.CreateCollector(GameMatcher.HelloWorldLog);
}
/// <summary>
/// 满足条件后 执行相应的逻辑
/// </summary>
/// <param name="entities"></param>
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entity in entities)
{
Debug.LogFormat("打印的消息为【{0}】", entity.helloWorldLog.message);
}
}
}
}
- 新建一个文件夹Systems 文件夹 下面创建一个InitSystem 类 来调用LogSystem的时机
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace HelloWorld
{
/// <summary>
/// 初始化系统
/// </summary>
public class InitSystem : IInitializeSystem
{
private readonly GameContext _gameContext;
public InitSystem( Contexts contexts)
{
_gameContext = contexts.game;
}
public void Initialize()
{
_gameContext.CreateEntity().AddHelloWorldLog("Hello World");
}
}
}
Contexts里面的 是用来处理数据的 和生成代码的Contexts是对应的。如图他增加一个参数 这里也就增加一个参数
- 再再 Systems 文件夹下 添加AddGameSystem脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HelloWorld
{
/// <summary>
/// 添加系统到框架内
/// </summary>
public class AddGameSystem : Feature
{
public AddGameSystem(Contexts contexts): base("AddGameSystem")
{
Add(new LogSystem(contexts));
Add(new InitSystem(contexts));
}
}
}
以上就吧Entitas框架的Helloworld做好了,就差 添加和Unity链接的桥梁了
- 新建一个Contoller文件夹新建一个一个脚本GameController
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HelloWorld
{
public class GameController : MonoBehaviour
{
private Systems _systems;
// Use this for initialization
void Start()
{
var contrxt = Contexts.sharedInstance;
_systems = new Feature("Systems").Add(new AddGameSystem(contrxt));
_systems.Initialize();
}
// Update is called once per frame
void Update()
{
_systems.Execute();
_systems.Cleanup();
}
}
}
接下来我们就看到了打印的Helloworld