Gameplay-03: WorldContext, GameInstance And Engine
FWorldContext
在 UE 中存在多种 World:
1 | namespace EWorldType |
FWorldContext
则负责管理这些 World,使用指针 ThisCurrentWorld
指向当前的 world,对 world 的切换已经在引擎内部实现
FWorldContext
还保存 world 中 level 切换的上下文,不过这里只负责传入要切换的目标 level,真正执行的位置在 UEngine::TickWorldTravel
中执行 level 切换
思考:Level 的切换信息不放在 World 中?
- 通过 OpenLevel 打开一个 PersistentLevel 时,引擎会释放当前 world 并创建一个新 world,如果将 Level 切换信息存放在 World 中,那么在这个过程中就又需要在释放 world 前把 level 的切换信息保存下来
- 对于其他关卡(作为流式关卡),在加载的时候只是在 world 中载入对象,不需要释放 world,所以可以存放在 world 中
思考:为何 World 和 Level 的切换要放在下一帧执行?
- Level 加载需要载入 Map、Mesh、Material 等,加载必然很慢,需要异步操作
- 异步操作的两种方式
- 先记录信息,再执行
- 通过命令模式向队列中压入命令再执行
UGameInstance
UGameInstance 中保存当前 FWorldContext 以及其他游戏的整体信息
可以将一些独立于 Level 的逻辑或数据放在 UGameInstance 中存储
UEngine
UEngine 派生出两个重要子类:UGameEngine 和 UEditorEngine,UEngine 自身用一个全局 GEngine 变量保存
因为 UE 的编辑器也是 UE 渲染出来的,为了区别编辑器和游戏,这里分成了两个子类来管理
- 对于编辑器,EditorWorld 的作用是预览,严格来说和 GameInstance 关系不大,所以没有 OwingGameInstance,而 PlayWorld 会保存一个 OwningGameInstance
- GameWorld 是 UGameEngine 唯一创建出来的,也就是 StandaloneGame,也会保存 GameInstance 指针
UGameplayStatics
1 | UCLASS () |
UGameplayStatics 作为一个静态类,给蓝图暴露了一些静态方法,当然这些方法也可以在 C++中使用
比如将屏幕上一点投射到世界空间,在 【Demo】多人TPS项目中用来计算准星发出的射线和世界空间物体的交点
1 | UGameplayStatics::DeprojectScreenToWorld() |
以及生成粒子发射器
1 | UGameplayStatics::SpawnEmitterAttached() |
总结
UE 使用 Object -> Actor + Component -> Level -> World -> WorldContext -> GameInstance -> Engine 这一套用来描述游戏世界的各个对象,接下来需要了解如何在这些对象的数据结构上表达游戏逻辑。
参考链接
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Fubuki の Donuts!