最近对于ECS的认知
最近又在折腾ECS框架。目的是做一个效率优先,性能不差的框架在服务器上使用。
在写之前一直有几个问题困扰着我。
Entity应该设计成struct还是class?
Component应该设计成struct还是class?
Arch type和稀疏集怎么选?
如何让逻辑编写效率高?
Entity应该设计成struct还是class?
一直有人诟病ET框架的Entity是class,效率低下,承载不了大量实体。
我怀疑他们没仔细看文档,文档里已经写明效率优先,牺牲缓存命中率。而且他们家游戏里哪里有数十万个实体?还有弱联网的单机游戏,根本就没有高效遍历组件的逻辑,更没必要提缓存命中率了。
并且,Entity是class还是struct和承载大量实体有个毛关系?数据都在Component上,Entity只是个索引罢了。system逻辑里遍历大量实体的数据,都是按查询的Compnents结果去修改的。
Component应该设计成struct还是class?
如果是为了缓存命中率,那么Component应该设计成struct。并且为了缓存命中率,component里不应该有引用类型的字段,除非遍历的时候不会进行访问。
Arch type和稀疏集怎么选?
一些ECS框架实现用的稀疏集,一些用Arch type。
首先,一定是Arch type的效率高于稀疏集的。
比如实现MovementSystem,需要查询具有Position和Velocity的实体,遍历去修改Position。
如果使用稀疏集存储component的话,需要在for循环里先查询Position再查询Velocity,Position和Velocity不是连续存储,所以缓存命中率一定是比Arch type低的。
Arch type是直接把具有一组组件的实体存储在一起,内存连续,这样遍历时缓存命中率100%。
但是如果新建一个MovementComponent,Position和Velocity放到组件里,此时内存就连续了。
如何让逻辑编写效率高?
优先要考虑的就是游戏类型,要不要用ECS,到底有没有大量实体,没有大量实体,就先考虑缓存命中率,很不切实际。
EC模式能让数据和逻辑解耦,逻辑更清晰,效率已经有了很大提升。
写游戏最重要的是首先要让游戏能跑起来,优化都是后面的事。别等原型没做出来,项目先没了。