[关闭]
@leviyuan 2017-08-05T10:02:56.000000Z 字数 10110 阅读 573

SuperMobs.lua.ecs

supermobs lua ecs unity

QQ图片20170803185521.jpg-15.4kB

名词解释

另类方式讲述ecs

有一个流水线,要做一种罐头

创建一个pool,名字叫罐头制作流水线

罐头由瓶子、盖子、水、糖浆、水果组成

我们最终要创建出的entity包含瓶子、盖子、水、糖浆、水果这五种component

流水线上有5道工序

需要5个system来实现这个过程

第一道工序,在合理的情况下(下游没有累积过多、总需求量没超),向流水线上放空瓶子

第一个system,在合适的时候,创建空entity,并添加瓶子组件

第二、三、四道工序,分别对应水、糖浆、水果,检查瓶子里没有自己要加的东西时,添加进去

第二、三、四个system,在entity上没有自己对应组件时,添加给entity

第五道工序,检查其他的都已经齐全,把盖子盖上

第五个system,当其他四个component都已经添加时,为entity添加盖子component

流水线把产品制作分成不同模块,方便分别改进优化
流水线为每个工人提供工作环境,单个工人不需要在意整体流程
产品出现问题时,可以在流水线上查找产品定位问题到单一工人
承担相同工作的工人可以在流水线上随意替换

ecs把流水线的好处带给coding

设计思路

使用ecs最大的难点是要转变设计思路,它与面向对象的程序设计思路相差甚远
下面从一个实际的需求开始讲述如何使用ecs的思路来设计解决方案

需求:服务器列表功能
1、服务器有 编号、名称、分组、排序、状态属性需要显示
2、需要自动选择玩家上次登录的服务器
3、玩家可以手动刷新服务器状态
4、服务器列表中要显示玩家在该服务器拥有的角色基本信息

一、基础数据结构设计

这一步需要设计出功能需要数据的最精简结构
这部分数据将是功能的核心数据,其他的数据都可以通过计算或者数据查询得到

在这个示例需求中,最核心的数据就是
    服务器固定信息:{编号、名称、分组、序号}
    服务器动态信息:{编号、状态}
    玩家信息:{上次登录的服务器编号}
    角色信息:{编号、名称、等级、所属服务器}
这样一个数据结构

PS:设计基础数据时要保证不同时变化的数据需要分开,示例中的服务器固定信息和动态信息
分开的好处是方便做数据匹配,可以让系统设计更加容易

二、完整的数据结构

在完整的数据结构里,将会数据的 整合、分组 设计
然后得出模块的Component设计

三、数据处理系统设计

这一步将会得到一些System的设计结论,从以下两个方向来思考

四、具体功能实现

汇总一下前面的结论,所有的Component如下:

lua版本API说明

Component

Matcher

pool

System

Group

  1. ecs.component.regist("A", "a")
  2. ecs.component.regist("B", "b")
  3. local p = ecs.pool.create("test")
  4. local group = p:getgroup(ecs.matcher.A)
  5. -- B组件的属性来做索引计算,但是group的声明中并没有涉及到B
  6. -- ecs内部更新时,不会认为B组件的变化与这个group有任何关系
  7. -- 所以索引值完全不正确,没法办法去使用
  8. group:addindex("b", function(entity)
  9. return entity.hasB and entity.B.b or 0
  10. end)
  11. -- 实际的逻辑中,如果用A+B作为group的特征描述也ok,那么可以这样声明group
  12. group = p:getgroup(ecs.matcher.A, eca.matcher.B)
  13. -- 如果只有A可以作为特征描述,B不与特征有直接关系,那么可以这样做
  14. -- 本质与getgroup(ecs.matcher.A)相同,但是向ecs系统说明了这个groupB有关
  15. group = p:getgroup(ecs.matcher.A, eca.matcher.A.any, eca.matcher.B.any)
  1. for i, entity in group:ipairs("ordername") do
  2. print(i, entity)
  3. end

Entity

Module

  1. {
  2. -- using UnityEngine;
  3. "A.B.*",
  4. "C.*",
  5. -- using C = UnityEngine.Camera;
  6. c = "D.EE",
  7. f = "D.XXXX"
  8. }

没有声明shorttable的情况下,ecs系统会在全局搜索以'.componentname'结尾的组件,如果只有一个,那就当做是这个组件来处理,如果不止一个,将会抛出error,"componet name XXXXX is not explicited"
以示例的shorttable来说明组件搜索过程:
1、查找“c = "D.EE"”这样的格式,如果匹配,那么就是等号右边就是组件的fullname
2、依次把componentname代入"A.B.*"这样格式,查找是否存在这样fullname的组件,如果有,查找结束
3、无视shorttable,去全局查找,有可能出现"componet name XXXXX is not explicited"的报错

编辑器的使用

延伸阅读

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注