GAME104第三节

视频:03.如何构建游戏世界 | GAMES104-现代游戏引擎:从入门到实践_哔哩哔哩_bilibili

让游戏活起来

GO:属性(property)+行为(behave)

现代游戏引擎将所有的东西抽象为GameOject GO 游戏对象。

属性和行为

假设目前有一个无人机对象,现在需要增加一种可以开火的无人机。

最初的方式使用派生继承的方式

image-20241028141339859

但是游戏世界没有完美的分类。因此现代的解决方案是把行为变成组件。

image-20241028140454675

  • UObject类似C#里的object

对象属性和行为优化:派生继承分类—>组件化

Tick

一般而言将每个GO的Tick都执行一遍即可让游戏动起来。

现代游戏引擎并不是按照每个对象进行Tick,而是将一个个系统Tick。

  • 最高效的方式是“流水线”。
  • 在计算机中,将同样的数据尽可能放在一起然后一次处理,这样最高效。

Tick的优化:每个GO的Tick进行一遍—>每个系统的Tick进行一遍

对象间互动

对象自行检测在其周围的对象,“告知”其做出“反馈”。这样直接的写被称为hardcode:

image-20241028142035676

现代引擎中,对象过多时,Hardcode的方式会出问题。因此使用了Events机制。

对象间互动优化:Hardcode–(解耦合)–>Events

游戏对象管理

当发生事件时,需要在成千上万个GO中通知到指定的GO,因此需要去管理游戏对象。

场景管理

场景中每个GO都会有一个guid,以及有自己的position。

场景管理时我们需要对场景进行划分管理。

不划分管理

最简单的场景管理方式。

直接遍历每一个对象进行逻辑处理。

问题:每个GO都有可能和其他GO进行交互,每一次要遍历一遍另外的物体,那么场景里有可能出现n(n-1)≈n方。当GO过多,就会爆炸。

image-20241028144659251

画格子管理

场景分布均匀、不大时,可以采用。

问题:场景不均匀、非常大时,会出问题。而现代游戏场景不均匀、非常大。

image-20241028144954009

层级结构管理

Hierarchical segmentation。

类似地址的写法。

image-20241028145252006

四叉树划分

按对象集划分,分层分割。

当每一块区域GO数量很多,那就不停的划分,就会形成树状的结构。

当任何一个事件发生时,发生的GO会知道自己所在节点的位置,当其需要寻找周边时直接查找父节点或者兄弟节点即可

image-20241028145325556

空间数据结构

image-20241028150257166

空间数据结构是场景管理的核心,实际引擎会有不同的数据结构使用。

Octree 八叉树

BVH :现代游戏引擎比较常用

总结

所有的对象都是一个object。

每个object都是用component-base的方法去描述他,用component去组合成不同的行为。

所有的component用Tick的方法去不断更新逻辑。

在所有的GO中,通过一套复杂的消息机制去彼此通讯。

针对大量的GO,我们需要一套非常高效的层次结构的场景管理机制。

物体之间的绑定

比如车和你绑定,车动你也动。这时GO tick时,一般会要求父节点先tick,然后子节点再去tick。

tick时序:很多的tick并行执行,如果让GO彼此之间通讯时,会出现一些不确定的混乱性。游戏引擎中,消息的传递很复杂!

在component中,有pretick和posttick的函数,就是为了解决各种各样时序性的问题。