中文文档:https://docs.killliu.com/docs/unity/entities/
ISystem和SystemBase的区别
Archetype和Chunk
相同组件的实体放在一起,也就是我们所说的内存块(Chunk)
Chunk有一个大小
https://blog.youkuaiyun.com/weixin_40124181/article/details/103716338
如果批量操作的entity都是同一个chunk下的效率会更高
放相同组件的实体的所有块,都属于同一个类型,也就是原型
在内存中会尽可能地将相同组件排列在一起, 一个chunk下会先存了相同组件的数组,然后才会换下一个组件的数组
SubScene
https://blog.youkuaiyun.com/weixin_38027841/article/details/136976174?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-136976174-blog-103921827.235%5Ev43%5Epc_blog_bottom_relevance_base8&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-136976174-blog-103921827.235%5Ev43%5Epc_blog_bottom_relevance_base8&utm_relevant_index=5
ecs下的entity的需要转换的gameobject放subscene下,其他不需要转成entity放scene下,subscene管理这个场景下的所有实体
https://blog.youkuaiyun.com/qq_36382054/article/details/103921827
使用的时候是二进制数据
创建的entity一定在subscene下,通过baker创建的,baker在哪个subscene,创建的entity就在哪个subscene
subscene中的entity数据在编译期间的时候转成entity二进制数据,所以在运行时候修改subscene里面的go,是不会及时生效的,要停止游戏重新烘焙。
托管Component和非托管Component的区别
Unity 不支持多线程 GC,只有主线程才能使用GC,而Burst支持多线程,Burst一般只能编结构体的代码
https://blog.youkuaiyun.com/biliskener/article/details/136966987#:~:text=%E5%9C%A8%E4%BD%BF%E7%94%A8Burst%E7%BC%96%E8%AF%91%E5%99%A8%E7%BC%96%E8%AF%91%E7%9A%84%E4%BB%A3%E7%A0%81%E4%B8%AD%E4%B8%8D%E8%83%BD%E4%BD%BF%E7%94%A8Managed%20Component%E3%80%82%20%E5%A6%82%E6%9E%9CManaged%20Component%E4%B8%AD%E4%BD%BF%E7%94%A8%E4%BA%86%E6%89%98%E7%AE%A1%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E6%89%8B%E5%8A%A8%E6%B7%BB%E5%8A%A0%E5%BA%8F%E5%88%97%E5%8C%96%2CClone%2C%E6%AF%94%E8%BE%83%E7%AD%89%E5%8A%9F%E8%83%BD%E3%80%82,%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AAManaged%20Component%E4%B9%9F%E9%9D%9E%E5%B8%B8%E7%AE%80%E5%8D%95%2C%E4%BD%A0%E5%8F%AA%E8%A6%81%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AAclass%2C%E7%BB%A7%E6%89%BF%E8%87%AAIComponentData%2C%E8%BF%99%E6%A0%B7%E5%B0%B1%E5%AE%9A%E4%B9%89%E5%A5%BD%E4%BA%86%E4%B8%80%E4%B8%AAManaged%20Component%20%28%E6%B3%A8%E6%84%8F%E9%9D%9E%E6%89%98%E7%AE%A1%E7%9A%84%E6%98%AF%E5%AE%9A%E4%B9%89struct%29%E3%80%82
ShareComponent
用这个来作为共享组件:网格,材质
ISystem里收集对应关注component的方法的写法
SystemHandle 和 Component LookUp
https://segmentfault.com/a/1190000044119689
System特性
System生命周期:
OnCreate第一次进入的时候调一次,OnUpdate
System具有唯一性
SystemGroup 特殊的系统
初始系统,逻辑系统,渲染相关系统(preLateUpdate)
onUpdate一样是循环调用
EntityCommandBuffer和EntityManager
https://blog.youkuaiyun.com/kylinok/article/details/131552505
我们对Entity的修改只能在主线程上进行,调用playback之后才是真正的执行,之前都是记录
https://zhuanlan.zhihu.com/p/258927066
创建实体会修改job chunk块,添加删除component都会造成这个entity内存块的移动,所以使用entitycommandbuffer同步点优化,不用多次移动内存块。有job使用了ecb,playback之前要等这个job执行完。
Unity的UI系统是设计为主线程的,这是为了保证游戏或者应用程序的线程安全性。在Unity中,UI系统的更新和绘制是在主线程上进行的,这就意味着如果你试图在子线程中更新UI,可能会出现问题
获取所有,某一种entity,一般通过world
访问Component最有效的方法
https://zhuanlan.zhihu.com/p/361627288
这篇文档说的componentdatafromentity就是lookup,他说的对。
Entity.Foreach可以被IJobEntity替代。
query查询可以在系统的OnCreate缓存起来,后续chunk修改是增量查询更新,提高性能
只获取一个组件
var config = SystemAPI.GetSingleton();
一个System相当于另外一个System的执行顺序
https://blog.youkuaiyun.com/qq_34287925/article/details/132775744?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-132775744-blog-131530041.235v43pc_blog_bottom_relevance_base8&spm=1001.2101.3001.4242.1&utm_relevant_index=3
TransformUsageFlags概念
https://blog.youkuaiyun.com/valaki/article/details/132602124
system之间传递数据的方法
https://www.cnblogs.com/uwatech/p/17635358.html
使用公共实体,系统之间使用SystemAPI.TryGetSingletonEntity就行了
system也是一个实体,给system加上一个component,然后另一个system通过systemhandle获得这个system上的component来传递数据,unmanager的system通过state.worldunmanaged.getunsafesystemref(systemHandle)来获取
直接通过world获得GetManagedSystem系统调用托管系统里面的方法
动态避障算法
异步日志方案
ScheduleParallel和Schedule的区别
ScheduleParallel是一个chunk一个线程。
多线程依赖
JobHandle,可以绑定多个Job,Complete()或者CompleteAll()
Burst编译
不支持gc,类中的静态方法也可以编译,在静态方法中可以使用native容器优化,就算不使用dots,静态方法也可以用burst优化
Version Number 组件版本号
监听某个组件是否发生变化
怎么在dots sample 中找到场景中某一个实体具体是代码里面哪一个entity?
搜索TagComponent,然后找到一个entity,看场景中高亮的是不是他
直接看这个Tag面板,找到认得出来的Tag Component
System可以跨场景运行,一个世界只能存在一个系统,多个世界不能有同一个系统
https://blog.youkuaiyun.com/ww1351646544/article/details/139390446
如果另外一个场景不需要运行某个系统,
这样加上限制,那个场景没有对应的component中就不会运行这个系统,或者设置enable为false
subscene下存放的内容
动态entity,只要是entity都在subscene,静态entity,可以直接用brd渲染,但是要自己处理视椎剔除,使用entity,
挂上这个脚本标记为静态优化
Aspect
语法糖,初始化的时候需要entity
具体代码的写法
1.class的Baker
2.在SystemState上调用这个接口,表示某个组件存在,这个System才会被激活。
否则OnUpdate都不执行
3.获取时间
4.查找entity或者组件的顺序
SystemAPI没有对应方法就用systemstate,还没有就用entitymanager
4.System里面处理job的依赖
https://zhuanlan.zhihu.com/p/260200067
Dependency: A JobHandle used to pass job dependencies between systems.
5.某个System只执行一次
6.设置修改Component的值
entityManager
通过RefRW修改
7.job和主线程都可以使用的组件数组
DynamicBuffer
dynamicBuffer不能并行写入,不能在IJobParallel里面用,写入要转成nativearray
8.经常修改的组件
LocalTransform,URPMaterialPropertyBaseColor
9.UI点击获取系统,然后调用system里面的方法获取entity之类的
GetOrCreateSystemManaged
10.系统里面怎么反向调用UI
11.slg游戏里面大地图subscene和具体某张地图里面subscene之间的数据怎么切换
https://zhuanlan.zhihu.com/p/382902170
应该是用多个subscene,游戏中动态禁用开启加载切换,新创建的entity跟着创建他的author放在对应的subscene下面
https://docs.killliu.com/docs/unity/entities/streaming-loading-scenes
用LoadSceneAsync 异步加载subscene的asset
12.subscene 数据非常大,如何和scene分割开来,不能打在一个ab里面
https://blog.youkuaiyun.com/u010294054/article/details/96170470
应该放一起就行了,subscene有自己的asset,subscene asset打不同的ab就行了
https://docs.killliu.com/docs/unity/entities/streaming-loading-scenes
13.游戏中环境subscene和动态创建的entity所在的subscene应该是不同的subscene,由不同的人编辑
14.ecs里面跟Transform相关的组件
LocalTransform,使用方便,方便设置position,scale
LocalToWorld , 只有一个矩阵,使用不方便
Parent Component用来设置Entity直接的父子关系,一个Entity最多只能有一个Parent Component。可以获得某个实体的parent,利用这个组件
设置了parent能在这里看到,加了会给对应entity自动加上child组件
15.组件可以当成过滤条件
16.IJobChunk使用,job中的时间要从外面传进去
ijobchunk中获取组件容器,通过typehandle,typehandle获得组件,需要chunk,获得是一个chunk下的所有组件。
chunk获得组件,GetRequiredComponentDataPtrRO或者GetNativeArray
lookup不需要chunk就可以获得组件容器,在调用的时候就已经获得,key就是entity,比如不同entity的同一个组件就会在同一个容器里面
17.SystemAPI.Query 查询条件
https://blog.youkuaiyun.com/valaki/article/details/132555234
https://blog.youkuaiyun.com/weixin_40124181/article/details/103855181
SystemAPI.Query返回的是是否可读写的组件引用,EntityQuery返回的是满足条件的entity
一个可以控制读写,一个只能读写
18.点一个UI控制一个entity
可能是通过entityquery获得的nativearray的数组里面来根据索引控制entity
19.DynamicBuffer copy 到一个新的nativeBuffer里面
World update allocator
https://zhuanlan.zhihu.com/p/679969486
https://docs.unity3d.com/Packages/com.unity.entities@1.1/manual/allocators-world-update.html
20.动态控制组件的启用状态,避免结构性变化。
SetComponentEnabled(Entity e, bool enable),query查询不会查询component enable为false的entity
21.state.RequireForUpdate(m_Query)
一些常见的报错
1.
意思是这个容器设置了可写又把它定义只读,所以造成了冲突会报错。
NativeContainer的竞争条件检查
说的是RW的只能读写同一个index的NativeArray,在多线程的job里面,
这里index方法里面读的index不是execute里面的index,可能会造成运行结果不一致,所以报错。
unity dots sample
https://github.com/Unity-Technologies/EntityComponentSystemSamples
在 Job System 或 Burst 编译的代码中,频繁的组件查询会带来性能瓶颈。ComponentLookup 通过 缓存组件类型的索引或句柄,避免重复的类型检查和查找操作,从而显著降低运行时开销