为了彻底理清 AActor 从“无”到“有”再到“运行” 的完整闭环,我将基于 UE5.7 源码(LevelActor.cpp, Actor.cpp, GameModeBase.cpp)和 Lyra 的实现,为你梳理出一条严丝合缝的调用链。
我们将这个过程分为三个核心阶段:生成(Spawn)、组装(Construction)、激活(Activation)。
第一阶段:生成与实例化 (The Birth)
目标:在内存中创建对象,并把它塞进世界(World)里。
UWorld::SpawnActor
调用者:你的游戏逻辑(如 ALyraGameMode::RestartPlayerAtPlayerStart)。
动作:检查碰撞、确定位置。如果一切正常,进入下一步。
StaticConstructObject_Internal
调用者:UWorld::SpawnActor。
动作:分配内存,调用 构造函数 (Constructor)。
关键点:此时 Actor 只是内存里的一个 C++ 对象,还没有 RootComponent,也没有进入世界的 Actor 列表。
AActor::PostActorCreated
调用者:UWorld::SpawnActor (在构造完成后立即调用)。
动作:这是 Actor 生命周期的第一个回调。
闭环意义:如果你需要在组件构建前做点什么(比如设置一些静态属性),就在这里。
第二阶段:组装与初始化 (The Assembly)
目标:运行蓝图脚本,挂上组件,并让组件“通电”。这是最复杂的环节。
AActor::PostSpawnInitialize
调用者:UWorld::FinishSpawningActor (由 SpawnActor 触发)。
动作:它是初始化的总指挥。如果 bDeferConstruction 为 false,它会立即执行以下步骤:
AActor::FinishSpawning
调用者:PostSpawnInitialize。
动作:
调用 ExecuteConstruction:运行 C++ 和蓝图的 Construction Script。此时,你的 RootComponent 和其他子组件被正式 NewObject 出来并挂载。
调用 PreInitializeComponents。
AActor::PreInitializeComponents
调用者:FinishSpawning。
动作:在组件初始化前最后一次干预机会。
Lyra 闭环:ALyraGameMode 在这里生成 GameState,确保在游戏逻辑跑起来之前,状态管理器已经就位。
IncrementalRegisterComponents
调用者:FinishSpawning。
动作:将所有组件注册到渲染系统、物理系统和音频系统中。
UActorComponent::InitializeComponent
调用者:FinishSpawning (遍历所有组件)。
动作:组件内部的初始化。例如,ULyraAbilitySystemComponent 会在这里注册 Tag 关系。
AActor::PostInitializeComponents
调用者:FinishSpawning。
动作:所有组件已就绪。此时你可以安全地调用 GetComponentByClass。
第三阶段:激活与运行 (The Activation)
目标:从“静态存在”变为“动态运行”,开始接收 Tick 和输入。
AActor::DispatchBeginPlay
调用者:UWorld::UpdateLevelStreaming 或 AGameModeBase::StartPlay。
动作:检查 bHasBegunPlay 标志,防止重复执行。
AActor::BeginPlay
调用者:DispatchBeginPlay。
动作:
注册 Tick 函数(如果开启了 Tick)。
处理初始的物理重叠(Overlaps)。
触发蓝图的 Event BeginPlay。
AGameModeBase::StartPlay
调用者:引擎主循环(当关卡加载完毕时)。
动作:通知 GameState 比赛正式开始。
Lyra InitState Chain
调用者:ULyraPawnExtensionComponent::BeginPlay。
动作:调用 TryToChangeInitState。这标志着 Actor 进入了 Lyra 特有的异步数据加载闭环,直到状态变为 GameplayReady,玩家才能真正操作角色。
总结:完整的执行闭环图
阶段 关键函数 谁调用的? 此时的状态
1. 出生 Constructor StaticConstructObject 只有内存,没有世界。
2. 落地 PostActorCreated UWorld::SpawnActor 进了世界,但没组件。
3. 装修 ExecuteConstruction FinishSpawning 蓝图跑完,组件挂好。
4. 通电 Pre/PostInitializeComponents FinishSpawning 组件注册完毕,内部逻辑启动。
5. 开业 BeginPlay DispatchBeginPlay 游戏开始,Tick 启动。
6. 就绪 InitState: GameplayReady Lyra Component Manager 数据加载完成,玩家可操作。
为什么这个闭环很重要?
如果你在 Constructor 里调用 GetWorld(),它会崩溃(因为还没进世界)。
如果你在 PreInitializeComponents 之前访问组件,它会返回空指针(因为组件还没 NewObject)。
如果你在 BeginPlay 之前尝试使用技能,它会失败(因为 Lyra 的 ASC 还在 InitState 的排队中)。
这就是 UE5 和 Lyra 共同构建的、严谨的 Actor 生命周期闭环。