ecs初识

ECS是什么

我们平时开发,总是会用到继承,子类继承自父类,然后子类复用父类的实现,或者子类重写父类的实现,再者子类相同函数名不同实现,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
private float _x, float _y;
virtual int GetSum()
{
return _x + _y;
}
}

class B : A {
private float _z;
override int GetSum()
{
return super.GetSum() + _z;
}
}

这样我们就可以实现了一个继承了,这里有个问题,子类对于父类的实现是不知道,属于封闭的,如果后期改动父类,子类也会改动,但是子类却不知道

ECS(entity component system)

ECS,可能一开始想到的是组件式开发,其实他跟组件式开发是两回事呢,以unity为例,定义一个类,类的定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class example : MonoBehaviour 
{
void Awake()
{
// do
}
void Update()
{
// do
}

}

这里面会在Update或者Awake做很多操作,例如更新位置等等。

ECS讲究的是component是数据(纯数据),System来负责处理这些数据,一个System理应关心少量的Component,Component是跟Entity挂钩的。一个Component的定义可能是:

1
2
3
4
public struct ComponentTest : IComponent 
{
public int speed;
}

这里用了struct,struct,内存存放在栈里面,函数调用如果不定义为ref 默认会copy一份数据,定义为struct的好处其实还是挺多的,首先就是不能给继承,避免开始说那种情况,父类改动,子类也改动了,struct一开始可以知道字节大小,方便做内存对齐,一开始可以开辟一大块的内存区出来。

System和Component,Entity的关系

游戏/应用会存在一个或者多个World,里面会有很多的Entity,一个Entity会存在很多的Component,Entity对Component的关系就是,增加删除,System就会根据Component过滤Entity,只处理自己关心的Component,所以System里面拿出来的Entity只是其中的一小部分,可能大部分是不是这个System处理的,System拿到Entity是根据内存排序了的,具体的因为Component是有序的,Entity只是一个载体,这样可以增加寻找的效率,System会把Component拿出来折腾,处理一波,然后以Component的方式存起来,这样做的好处有什么呢,首先,内存命中率高很多(虽然大部分应用不需要考虑),其次就是System的处理可以放在线程里面去做,因为他跟其他没什么关系,他只有一堆数据,然后渲染线程再根据这些更改进行渲染,再者就是逻辑完全分离,各司其职,你可以只关心自己的(可能是改动的,不改动不变化)。Unity的ECS和一开始所说的守望先锋的ECS不太一样,Unity目前正在大力开发这个ECS,正在想着用它来替代以前的那个面向对象方式。

参考

网上也有很多的ECS文章,大多都是泛泛而谈,估计很多都没有实操过,哪怕实操过也没有很好利用起来多线程的魅力,跟传统开发相距甚远

https://zhuanlan.zhihu.com/p/71216954

打赏

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信