# Actor生命周期
参考文档:
可以把Actor看成是Level中的基本单位。
Actor的体系如下:
# 代码追踪
下面是在UE4中调试代码来追踪Actor的生命周期,注意如果出现下面错误:
The Breakpoint will not currently be hit. No executable code associated with this line
需要下载该引擎对应的调试符号。
# 引擎启动
下面是拿4.26引擎来做的调试:引擎启动会执行:
- 执行UE4主入口程序Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp中的WinMain函数。
- 执行Engine\Source\Runtime\Launch\Private\Launch.cpp中的GuardedMain。
- 执行Engine\Source\Editor\UnrealEd\Private\UnrealEdGlobals.cpp中的EditorInit。
- 执行Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp中的FEngineLoop::Init()。
- 执行Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp中的Init。
- 执行Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp中的Init。
# Actor生命周期
- 当在UE4编辑器中点击Play时,旧版本会执行EditorEngine中的PlayInEditor(),从4.25开始,这个入口被废弃了,取而代之的是StartPlayInEditorSession(),在这个里面加断点。
- 在UEditorEngine::CreateInnerProcessPIEGameInstance中:
- 来生成GameInstance实例。
- GameInstance实例会调用InitializeForPlayInEditor来初始化编辑器。
- 获取WorldContext,如果没有则创建一个。
- 通过复制来创建一个PIE World。
- 如果创建成功则给新World赋予当前GameInstance,并添加到WorldContext中去。
- GameInstance->StartPlayInEditorGameInstance。开始在EditorGameInstance中运行。
- PlayWorld->SetGameMode(URL):初始化GameMode。如果GameWorldSetting中设置了,则使用该GameMode,如果没有则使用默认的。
- PlayWorld->CreateAISystem():创建AI系统。
- PlayWorld->InitializeActorsForPlay(URL):初始化Actors。
- AreActorsInitialized():判断Actor是否被初始化了。
- 初始化网络Actors。
- ULevel::RouteActorInitialize():初始化Actor以及它们身上的components。
- Actor::PreInitializeComponents():预初始化组件,如果是PlayerController,则打开输入,其他则要手动打开并Register才行。
- Actor->InitializeComponents():初始化组件。
- AActor::PostInitializeComponents():如果组件要复制的话进行网络复制。
- AreActorsInitialized():判断Actor是否被初始化了。
- FNavigationSystem::AddNavigationSystemToWorld():生成导航系统。
- PlayWorld->BeginPlay():开始游戏
- GetAuthGameMode():获取服务器GameMode。
- GameMode->StartPlay():使用GameMode开始游戏。执行BeginPlay。
- GameState->HandleBeginPlay()
- GetWorldSettings()->NotifyBeginPlay()
- It->DispatchBeginPlay(bFromLevelLoad);
- BeginPlay();
- RegisterAllActorTickFunctions():注册Tick事件。
- 处理组件中的BeginPlay。
- ReceiveBeginPlay():执行蓝图中的BeginPlay。
- BeginPlay();
- It->DispatchBeginPlay(bFromLevelLoad);
- GetWorldSettings()->NotifyBeginPlay()
- GameState->HandleBeginPlay()
- GetAISystem()->StartPlay():AI系统开始工作。
# Actor生成流程
下面来看下使用SpawnActor的执行流程:
- AActor::GetWorld():获取当前World实例。
- UWorld::SpawnActor():开始生成
- check( CurrentLevel ); 检查是否是当前关卡。
- if( Class->HasAnyClassFlags(CLASS_Deprecated) ):当前类是否是丢弃的。
- if( Class->HasAnyClassFlags(CLASS_Abstract) ):当前类是否是抽象类(UClass(Abstract))。
- if( !Class->IsChildOf(AActor::StaticClass()) ):当前类是否是一个Actor。
- if (SpawnParameters.Template != NULL && SpawnParameters.Template->GetClass() != Class):模板类不匹配生成类。
- if (bIsRunningConstructionScript && !SpawnParameters.bAllowDuringConstructionScript):是否在构造脚本中运行。
- if (LevelToSpawnIn == NULL):查看要生成Actor的Level。
- if (SpawnParameters.bNoFail):检测周围是否有其他碰撞,如果有的话可选择生成或不生成。
- NewObject<AActor>():使用NewObject来生成类。
- LevelToSpawnIn->Actors.Add( Actor ):将Actor添加到当前Level的Actors容器中。
- Actor->PostSpawnInitialize():生成Actor后初始化过程。获取创建时间,设置网络规则,设置Owner。它的一般流程如下:
- Actor sets up the basics.
- Actor gets PreInitializeComponents()
- Actor constructs itself, after which its components should be fully assembled
- Actor components get OnComponentCreated
- Actor components get InitializeComponent
- Actor gets PostInitializeComponents() once everything is set up
- AddNetworkActor( Actor ):添加网络的Actor。
# Actor销毁流程
下面是Actor的销毁过程:
- IsPendingKillPending():是否被标记为被销毁状态。
- World->DestroyActor( this, bNetForce, bShouldModifyLevel ):通过当前世界来进行销毁。
- if (ThisActor->IsPendingKillPending()):判断是否已经标记为被销毁。
- UWorld::IsGameWorld():判断是否为GameWorld。
- 判断当前是否能销毁网络Actor,只有服务端能销毁网络Actor。
- IStreamingManager::Get().NotifyActorDestroyed( ThisActor ):通知Actor被销毁。
- ThisActor->Destroyed():告诉Actor它是否要被销毁。
- RouteEndPlay(EEndPlayReason::Destroyed):进行销毁。
- EndPlay(EndPlayReason);
- ReceiveEndPlay(EndPlayReason):组件执行EndPlay。
- EndPlay(EndPlayReason);
- RouteEndPlay(EEndPlayReason::Destroyed):进行销毁。
- ThisActor->GetAttachedActors(AttachedActors):获取AttachedActor。
- 判定我们被销毁的Actor是否绑定到其他Actor上边,如果是的话Detach。
- ThisActor->ClearComponentOverlaps():删除自己的组件。
- 通知网络,当前Actor已经被销毁。
- RemoveActor( ThisActor, bShouldModifyLevel ):把Actor从Actor列表中移除。
- ThisActor->UnregisterAllComponents():清除Actor的所有组件。
- 标记Actor为Pending Kill。
- 注销Actor的Tick函数。