这段时间在看UE的关卡切换的内容,发现要补的内容有很多,比如UE的整体结构。
本文主要参考了大钊的InsideUE4,记录一下自己的理解和想法。
本文从上往下梳理UE的结构。先放一张结构图。
Engine
首先是引擎级别,UE编辑器本身也是一个引擎。所以分为两个部分,这里我们主要研究UGameEngine
在Engine基类里保存会保存多个WorldContext。一般来说,UE只能同时存在一个World,但是可以相互切换。
UGameInstance
UGameInstance会保存当前的WorldContext和其他游戏的信息。不管Level如何切换,GameInstance中的信息都会一直存在。
WorldContext
一个World管理多个Level,并负责这些Level的加载和释放,下面是一些World类型
namespace EWorldType
{
enum Type
{
None, // An untyped world, in most cases this will be the vestigial worlds of streamed in sub-levels
Game, // The game world
Editor, // A world being edited in the editor
PIE, // A Play In Editor world
Preview, // A preview world for an editor tool
Inactive // An editor world that was loaded but not currently being edited in the level editor
};
}
而用来管理World的是WorldContext,从一个World切换到另一个比如说从编辑器的预览切换到PIE的时候,FWorldContext就用来保存切换过程和World上下文信息。一个World只有一个PersistentLevel,比如切换Level的时候,也会需要WorldContext参数,因为UE在切换PersistentLevel的时候其实是卸载一个World再加载一个新的。
因此Level的切换信息不能放在World里,这样做需要在卸载之前进行另存,直接放在WorldContext里面,在切换Level的时候用SetClientTravel,其实是从引擎发起的,这个时候切换的地图信息都保存WorldContext里。
World
World里保存了一个主Level和很多其他SubLevel。在同一个World里切换Level可以是无感切图。(切图还在研究中),其中的WorldSettings以主Level为主。
Level
Level保存了本Level的所有Actor,
Actor
- Actor本身是没有Transform的,是它的SceneComponent给了它这种能力
- Actor的AttachtoActor接口其实是把Actor的SceneComponent连在了一起
- Actor不一定有实例化,放在场景里肯定是被实例化的,但也可能场景没有。
- Actor可以挂载多个SceneComponent,同时SceneComponent又可以递归挂载下去
补充结构
LocalPlayer,保存在GameInstance,用来给PlayerController设置Player,是PlayerController控制角色的基础来源(至于为什么还待考察)
一些疑问解答:
关于World切换的问题:今天在群里请教了大钊,只有在切换不属于一个关卡的Map才会加载卸载world,而切换同一个关卡中的SteamLevel的时候是不会执行World的加载卸载操作的。