unity游戏开发之entitas框架
aaarticlea/png;base64,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" alt="" />
var context = contexts.game; var movables = context.GetGroup(GameMatcher.Movable);
var count = movables.count; // count is 0, the group is empty var entity1 = context.CreateEntity();
entity1.isMovable = true;
var entity2 = context.CreateEntity();
entity2.IsMovable = true; count = movables.count; // count is 2, the group contains the entity1 and entity2 // GetEntities() always provides an up to date list
var movableEntities = movables.GetEntities();
foreach (var e in movableEntities) {
// Do sth
} entity1.Destroy();
entity2.Destroy(); count = movables.count; // count is 0, the group is empty
var matcher = GameMatcher.Movable; GameMatcher.AllOf(GameMatcher.Movable, GameMatcher.Position); GameMatcher.AnyOf(GameMatcher.Move, GameMatcher.Position); GameMatcher
.AllOf(GameMatcher.Position)
.AnyOf(GameMatcher.Health, GameMatcher.Interactive)
.NoneOf(GameMatcher.Animating);
- IInitializeSystem: 只执行一次 (system.Initialize())
- IExecuteSystem: 每帧执行 (system.Execute())
- ICleanupSystem: 在其他系统完成后每一帧执行(system.Cleanup())
- ReactiveSystem: 当观察的group改变时执行(system.Execute(Entity[]))
public class MoveSystem : IExecuteSystem {
public void Execute() {
// Do sth
}
} public class CreateLevelSystem : IInitializeSystem {
public void Initialize() {
// Do sth
}
} public class RenderPositionSystem: ReactiveSystem<GameEntity> { public RenderPositionSystem(Contexts contexts) : base(contexts.Game) { } protected override Collector<GameEntity> GetTrigger(IContext<GameEntity> context) {
return context.CreateCollector(GameMatcher.Position);
} protected override bool Filter(GameEntity entity) {
// check for required components (here it is position and view)
return entity.hasPosition && entity.hasView;
} protected override void Execute(List<GameEntity> entities) {
foreach (var e in entities) {
// do stuff to the matched entities
e.view.gameObject.transform.position = e.position.position;
}
}
}
var systems = new Systems(contexts)
.Add(new CreateLevelSystem(contexts))
.Add(new UpdateBoardSystem(contexts))
.Add(new MoveSystem(contexts))
.Add(new RenderPositionSystem(contexts)); // Call once on start
systems.Initialize(); // Call every frame
systems.Execute();
using Entitas; public class MyInitSystem : IInitializeSystem { public void Initialize() {
// Initialization code here
} }
using Entitas; public class MyExecSystem : IExecuteSystem { public void Execute() {
// per-frame code goes here
} }
public class MyCleanupSystem : ICleanupSystem { public void Cleanup() {
// cleanup code here
// runs after every execute and reactive system has completed
} }
using System.Collections.Generic;
using Entitas; public class MyReactiveSystem : ReactiveSystem<MyContextEntity> { public MyReactiveSystem (Contexts contexts) : base(contexts.MyContext) {
// pass the context of interest to the base constructor
} protected override ICollector<MyContextEntity> GetTrigger(IContext<MyContextEntity> context) {
// specify which component you are reacting to
// return context.CreateCollector(MyContextMatcher.MyComponent); // you can also specify which type of event you need to react to
// return context.CreateCollector(MyContextMatcher.MyComponent.Added()); // the default
// return context.CreateCollector(MyContextMatcher.MyComponent.Removed());
// return context.CreateCollector(MyContextMatcher.MyComponent.AddedOrRemoved()); // combine matchers with AnyOf and AllOf
// return context.CreateCollector(LevelMatcher.AnyOf(MyContextMatcher.Component1, MyContextMatcher.Component2)); // use multiple matchers
// return context.CreateCollector(LevelMatcher.MyContextMatcher, MyContextMatcher.Component2.Removed()); // or any combination of all the above
// return context.CreateCollector(LevelMatcher.AnyOf(MyContextMatcher.Component1, MyContextMatcher.Component2),
// LevelMatcher.Component3.Removed(),
// LevelMatcher.AllOf(MyContextMatcher.C4, MyContextMatcher.C5).Added());
} protected override bool Filter(MyContextEntity entity) {
// check for required components
} protected override void Execute(List<MyContextEntity> entities) {
foreach (var e in entities) {
// do stuff to the matched entities
}
}
}
public interface PositionViewEntity : IEntity, IPosition, IView {} public partial class EnemyEntity : PositionViewEntity {}
public partial class ProjectileEntity : PositionViewEntity {} public class ViewSystem : MultiReactiveSystem<PositionViewEntity, Contexts> { public ViewSystem(Contexts contexts) : base(contexts) {} protected override ICollector[] GetTrigger(Contexts contexts) {
return new ICollector[] {
contexts.Enemy.CreateCollector(EnemyMatcher.Position),
contexts.Projectile.CreateCollector(ProjectileMatcher.Position)
};
} protected override bool Filter(PositionViewEntityentity) {
return entity.hasView && entity.hasPosition;
} protected override void Execute(List<PositionViewEntity> entities) {
foreach(var e in entities) {
e.View.transform.position = e.Position.value;
}
}
}
using Entitas; public class InputSystems : Feature
{
public InputSystems(Contexts contexts) : base("Input Systems")
{
// order is respected
Add(new EmitInputSystem(contexts));
Add(new ProcessInputSystem(contexts));
}
}
Systems createSystems(Contexts contexts) { // order is respected
return new Feature("Systems") // Input executes first
.Add(new InputSystems(contexts))
// Update
.Add(new GameBoardSystems(contexts))
.Add(new GameStateSystems(contexts))
// Render executes after game logic
.Add(new ViewSystems(contexts))
// Destroy executes last
.Add(new DestroySystem(contexts));
}
- [Context]: 可以使用此特性使组件仅在指定的context中可用;例如 [MyContextName], [Enemies], [UI]....提高内存占用。它还可以创建组件。
- [Unique]: 代码生成器将提供额外的方法,以确保最多存在一个具有该组件的实体。
- [FlagPrefix]:仅可用于支持标记组件的自定义前缀。
- [PrimaryEntityIndex]: 可用于将实体限制为唯一的组件值。
- [EntityIndex]: 可用于搜索具有组件值的实体。
- [CustomComponentName]: 为一个类或接口生成具有不同名称的多个组件。
- [DontGenerate]: 代码生成器不会使用此属性处理组件。
- [Cleanup]: 代码生成器将生成删除组件或销毁实体的系统。
- 遵循这个框架的规则去写代码,代码结构清晰。
- ECS这种模式,耦合度就很低,所有的游戏物体都是组件的组合而已,可扩展性强,通过合理组合component就能配置出一个新的游戏物体。
- 很方便的管理所有实体状态,entitas提供了类似状态机的功能,当感兴趣的某个属性发生变化时,能在System中很方便的做出响应,不管什么状态,都能很方便的做出对应处理。
- unity本身的开发模式就类似ECS,unity2018更是推出了最新的ECS框架,entitas很符合这种开发模式
- entitas自开源以来,一直在更新维护,并受到了unity官方的认可,在unite大会上都有提到。所以,这个框架还是很靠谱的。
- 国内资料少,上手难度高。国内用这个框架开发的特别少,遇到问题需要自己爬坑。
- 不适合小项目。小项目用entitas反而麻烦
- entitas更新太快,官方wiki文档更新没有跟上,比如,我在看官方Demo-MatchOne的时候,有个Event的Attribute, wiki上暂时还没有这个的
- 代码热更方面是个问题, entitas基本对unity开发定了一套完整的规则,特别是有Code Generate,如果项目发布后想要更新加入新的代码会很麻烦,官方对此也没有说明,目前好像也没有人分享在entitas中加入lua热更的功能
unity游戏开发之entitas框架的更多相关文章
- Unity游戏开发之C#快速入门
C#是微软团队在开发.NET框架时开发的,它的构想接近于C.C++,也和JAVA十分相似,有许多强大的编程功能. 个人感受是C#吸收了众多编程语言的优点,从中可以看到C.C++.Java.Javasc ...
- Unity游戏开发之“屏幕截图”
原地址:http://sygame.lofter.com/post/117105_791680 在unity游戏开发中,可能会遇到在游戏中截屏的效果.这儿提供两种截屏方法.(方法二提供显示截图缩略图代 ...
- Unity游戏开发之“分层碰撞”
有没有同学遇到过这样的情况:在游戏开发3D游戏中非经常见,比方让一个物体能穿过一个物体 而还有一个物体不能穿过这个物体,并且3个物体都不能穿过地面.在unity中这样的情况的处理是通过分层碰撞来解决的 ...
- unity游戏开发之NGUI的UISprite染色
游戏的UI开发中常常会遇到染色问题.比如button失效变灰的效果,同一个道具通过策划表配的颜色值染上红绿蓝紫等颜色,效果例如以下 最笨最挫的方法当然是让美术多出几个资源图.这种一个缺点是浪费资源,在 ...
- Cocos2d-x 3.x游戏开发之旅
Cocos2d-x 3.x游戏开发之旅 钟迪龙 著 ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x ...
- 【转载】浅谈游戏开发之2D手游工具
浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android 程序设计: 其它 编程语言: 引擎/SDK ...
- [整理]Unity3D游戏开发之Lua
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读
---------------------------------------------------------------------------------------------------- ...
- iOS游戏开发之UIDynamic
iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ...
随机推荐
- python 实现判断一个用户输入字符串是否是小数的小程序
要判断一个字符串是否是小数:1先判断小数点的个数,即如果是小数,则必须有且仅有一个'.'号2再分别判断'.'号的左右两边是否是数字: 判断左边时,如果负数,则左边包含'-'号:必须以'-'号开头(校验 ...
- 自己从0开始学习Unity的笔记 I (C#字符串转换为数字)
我基本上从0开始学习编程,运算符基本上跳过,因为知道了 “=”这个符号相当于赋值,然后“==”才是等于,其他和普通运算符号差不都,也就跳过了. 最基础的赋值那种,我看了下代码,似乎没什么难度,估计新手 ...
- 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造
第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造 MVC默认模板的视觉设计从MVC1到MVC3都没有改变,比较陈旧了:在MVC4中做了升级,好看些,在不同的分辨率下,也能工作得 ...
- netty网络通信中的tcp拆包问题
工作中的一个项目,我们的一个应用与银行系统进行tcp通信的时候,银行下送的报文有时会分多次返回.在tcp中这种数据包分多次小数据包发送的情况成为拆包问题. 其中一个,也是最常见的思路就是在报文的报文头 ...
- AJPFX的资金安全性
AJPFX承诺保证客户资金安全,并严格按照英国的相关规章制度从事经营活动.客户资金存放于投资级银行的独立账户中.通过实行公司资产与客户资金分别保管,在发生无偿债能力的罕见情况下,客户可获退还独立存放资 ...
- Exp6 信息搜集与漏洞扫描 20164323段钊阳
20164323 Exp6 信息搜集与漏洞扫描 回答问题 1.哪些组织负责DNS,IP的管理. 全球根服务器均由美国政府授权的ICANN统一管理,负责全球的域名根服务器.DNS和IP地址管理.全球一共 ...
- Django signal 信号机制的使用
Django中提供了"信号调度",用于在框架执行操作时解耦,当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作 一.Django中内置的 signal 类型主要包含以下几 ...
- 七,mysql优化——表的垂直划分和水平划分
1,表的水平划分 如果一个表的记录数太多,比如成千上万条,而且需要经常检索,那么我们有必要化整为零.如果我拆成100个表,那么每个表只有10万条记录.当然需要数据在逻辑上可以划分.一个好的划分依据,有 ...
- 用node.js写一个简单爬虫,并将数据导出为 excel 文件
引子 最近折腾node,最开始像无头苍蝇一样到处找资料,然而多数没什么卵用,都在瞎比比.在一阵瞎搞后,我来分享一下初步学习node的三个过程: 1 撸一遍NODE入门,对其有个基本的了解: 2 撸一遍 ...
- PHP之旅4 php 超全局变量
预定义数组: 自动全局变量---超全局数组 1.包含了来自web服务器,客户端,运行环境和用户输入的数据 2.这些数组比较特别 3.全局范围内自动生效,都可以直接使用这些数组 4.用户不能自定义这些数 ...