[UE学习笔记][基于源码] 理解 Gameplay

[UE学习笔记][基于源码] 理解 Gameplay

基于 UE 5.7 引擎源码(Engine/Source/Runtime/Engine/Private/


完整生命周期

UActorComponent AActor AWorldSettings AGameStateBase AGameModeBase ULevel UWorld GEngine UActorComponent AActor AWorldSettings AGameStateBase AGameModeBase ULevel UWorld GEngine CDO 默认值整体复制到实例 Details Panel 中的属性覆盖值(delta)写入实例 子对象/组件引用重定向到本实例 loop [关卡中每个 AActor] 此后属性已就位,组件引用已解析 注册所有组件到世界 ⚠️ 仅 PIE / 非 Cook 环境(bRerunConstructionScript=true) SCS 执行,创建蓝图组件 loop [所有 Level-placed AActor] 最早的 GameMode 初始化点 Phase 1 loop [所有 AActor] Phase 2 bActorInitialized = true loop [所有 AActor] Phase 3 loop [所有 AActor(非 ChildActor)] 跳过,BeginPlay 由 NotifyBeginPlay 统一触发 alt [HasBegunPlay() == true(流送关卡)] [HasBegunPlay() == false(初始加载)] loop [所有 Level] loop [所有 AActor(按 Actors 数组顺序)] ── 唯一的一帧 ── 默认 TG_PrePhysics;物理在 StartPhysics~EndPhysics 之间模拟 loop [TG_PrePhysics → StartPhysics → DuringPhysics → EndPhysics → PostPhysics → PostUpdateWork → LastDemotable] 无 Actor 绑定的 Latent Action SetTimer / FTimerHandle 回调在此触发 ── 关闭 ── loop [所有 AActor] LoadMap() / LoadPackage() 1 NewObject(CDO as template) 2 UObject::Serialize() 3 PostLoadSubobjects() 4 PostLoad() 5 InitWorld() 6 InitializeActorsForPlay(URL) 7 UpdateWorldComponents(bRerunCS) 8 RerunConstructionScripts() 9 ExecuteConstruction() 10 📢 UserConstructionScript() 11 🔓 OnConstruction(Transform) 12 🔓 InitGame(Map, Options) 13 RouteActorInitialize() 14 🔓 PreInitializeComponents() 15 InitializeComponents() 16 🔓 InitializeComponent() 17 🔓 PostInitializeComponents() 18 DispatchBeginPlay(bFromLevelStreaming=true) 19 BeginPlay() 20 🔓 OnWorldBeginPlay [WorldSubsystem] 21 🔓 StartPlay() 22 🔓 HandleBeginPlay() 23 🔓 NotifyBeginPlay() 24 📢 OnWorldPreBeginPlay.Broadcast() 25 DispatchBeginPlay() 26 SetBegunPlay(true) 27 (return) 28 📢 OnWorldBeginPlay.Broadcast() 29 Tick(DeltaTime) 30 FActorTickFunction::ExecuteTick() 31 FActorComponentTickFunction::ExecuteTick() 32 LatentActionManager.ProcessLatentActions(nullptr) 33 TimerManager.Tick() 34 EndPlay(Quit) 35 BeginTearingDown() 36 RouteEndPlay(Quit) 37 🔓 OnWorldEndPlay [WorldSubsystem] 38 SetBegunPlay(false) 39 CleanupWorld() 40

图注

  • 🔓 该函数为 virtual,可在 C++ 子类中 override
  • 📢 触发蓝图事件或委托广播,可在蓝图中响应
  • RouteEndPlay()DispatchBeginPlay()InitializeComponents() 无标记,为非虚引擎内部调度函数
  • Phase 3 标注"跳过"是初始加载最容易误解的地方------BeginPlay 由后续 NotifyBeginPlay 统一触发,而非 RouteActorInitialize
  • Component 的 ReceiveBeginPlay 先于 Actor 的 ReceiveBeginPlay(蓝图 Event BeginPlay)
  • EndPlay 顺序与 BeginPlay 相反:Actor 蓝图先收到通知,Component 后收到

DispatchBeginPlay & RouteEndPlay

DispatchBeginPlay

UActorComponent AActor UActorComponent AActor bHasBegunPlay = true loop [所有已注册 Component] ActorHasBegunPlay = EActorBeginPlayState::HasBegunPlay DispatchBeginPlay() 1 🔓 BeginPlay() 2 RegisterAllActorTickFunctions() 3 RegisterAllComponentTickFunctions() 4 🔓 BeginPlay() 5 📢 ReceiveBeginPlay 6 📢 ReceiveBeginPlay 7

RouteEndPlay

UActorComponent AActor UActorComponent AActor bHasBegunPlay = false loop [所有 Component(已 BegunPlay)] RouteEndPlay(Reason) 1 🔓 EndPlay(Reason) 2 📢 ReceiveEndPlay(Reason) 3 📢 OnEndPlay.Broadcast(Reason) 4 🔓 EndPlay(Reason) 5 📢 ReceiveEndPlay(Reason) 6 UninitializeComponents() 7


Tick 详细流程

FActorTickFunction::ExecuteTick

AActor AActor 该 Actor 绑定的 Delay 等 Latent Action 在此恢复 FActorTickFunction::ExecuteTick() 1 🔓 Tick(DeltaSeconds) 2 📢 ReceiveTick(DeltaSeconds) 3 LatentActionManager.ProcessLatentActions(this) 4

FActorComponentTickFunction::ExecuteTick

UActorComponent UActorComponent FActorComponentTickFunction::ExecuteTick() 1 🔓 TickComponent(DeltaSeconds) 2 📢 ReceiveTickComponent(DeltaSeconds) 3


运行时 Spawn

UWorld::SpawnActor

UActorComponent AActor UWorld 调用方 UActorComponent AActor UWorld 调用方 构造函数执行,CDO 默认属性复制到实例 设置 Transform 到 RootComponent 有原生根组件时注册,纯蓝图类可能延迟 FinishSpawning 不在此处调用,初始化未完成 alt [bDeferConstruction == false] [bDeferConstruction == true] SpawnActor(Class, Transform, Params) 1 NewObject(CDO as template) 2 PostSpawnInitialize(bDeferConstruction) 3 FixupNativeActorComponents() 4 🔓 OnComponentCreated() [原生组件] 5 RegisterAllComponents() 6 🔓 PostActorCreated() 7 FinishSpawning(Transform) 8 返回 Actor 指针(BeginPlay 已执行完) 9 返回 Actor 指针(未完成初始化!) 10


SpawnActorDeferred

AActor UWorld 调用方 AActor UWorld 调用方 ── 窗口期:Construction Script / BeginPlay 均可读到以下赋值 ── SpawnActorDeferred(Class, Transform) 1 SpawnActor(bDeferConstruction=true) 2 返回 Actor 指针(未完成初始化!) 3 MyActor->>Prop = Value 4 UGameplayStatics::FinishSpawningActor(Actor, Transform) 5 FinishSpawning(Transform) 6 返回完成初始化的 Actor 指针 7


蓝图 Spawn Actor from Class

AActor UWorld UGameplayStatics 蓝图节点 AActor UWorld UGameplayStatics 蓝图节点 ── 窗口期:Expose on Spawn 引脚赋值 ── loop [每个 Expose on Spawn 引脚] [节点编译后展开为以下三段] 1 BeginDeferredActorSpawnFromClass() 2 SpawnActorDeferred() 3 (return) 4 返回 Actor 指针(未完成初始化!) 5 Actor->>ExposedProp = PinValue 6 FinishSpawningActor(Actor, Transform) 7 FinishSpawning(Transform) 8 返回完成初始化的 Actor 指针 9


FinishSpawning

UActorComponent AActor 调用方 UActorComponent AActor 调用方 SCS 执行,创建蓝图组件 bActorInitialized = true BeginPlay 等待 NotifyBeginPlay 统一触发 alt [World.HasBegunPlay() == true] [World.HasBegunPlay() == false] FinishSpawning(Transform) 1 ExecuteConstruction(Transform) 2 📢 UserConstructionScript() 3 🔓 OnConstruction(Transform) 4 PostActorConstruction() 5 🔓 PreInitializeComponents() 6 InitializeComponents() 7 🔓 InitializeComponent() [bWantsInitializeComponent=true 时] 8 🔓 PostInitializeComponents() 9 DispatchBeginPlay() 10 FinishSpawning 返回 11

图注

  • SpawnActor 返回时 BeginPlay 已执行完,调用方拿到的是完全初始化的指针
  • SpawnActorDeferred 返回时 初始化未完成 ,必须调用 FinishSpawningActor 才能完成
  • 蓝图节点内部就是 Deferred 模式,Expose on Spawn 引脚在窗口期自动赋值

运行时销毁

UWorld::DestroyActor

UActorComponent ULevel UWorld AActor 调用方 UActorComponent ULevel UWorld AActor 调用方 IsPendingKillPending → 直接返回 true(幂等) IsActorBeginningPlay → 推迟到 BeginPlay 结束后执行 标记为待 GC,下次 GC 时释放内存 🔓 Destroy() 1 DestroyActor(this) 2 📢 OnActorDestroyed.Broadcast() 3 🔓 Destroyed() 4 RouteEndPlay(EEndPlayReason::Destroyed) 5 📢 ReceiveDestroyed() 6 📢 OnDestroyed.Broadcast() 7 DetachAllSceneComponents(子 Actor 解绑) 8 RemoveActor() 9 📢 OnActorRemovedFromWorld.Broadcast() 10 UnregisterAllComponents() 11 MarkAsGarbage() 12 (return) 13


源码速查

函数签名 源码位置
UWorld::InitializeActorsForPlay() Source/Runtime/Engine/Private/World.cpp:5842
UWorld::BeginPlay() Source/Runtime/Engine/Private/World.cpp:6044
UWorld::EndPlay() Source/Runtime/Engine/Private/World.cpp:6080
UWorld::SpawnActor() Source/Runtime/Engine/Private/LevelActor.cpp:455
ULevel::RouteActorInitialize() Source/Runtime/Engine/Private/Level.cpp:3817
AGameModeBase::StartPlay() Source/Runtime/Engine/Private/GameModeBase.cpp:204
AGameStateBase::HandleBeginPlay() Source/Runtime/Engine/Private/GameStateBase.cpp:205
AWorldSettings::NotifyBeginPlay() Source/Runtime/Engine/Private/WorldSettings.cpp:353
AActor::PostSpawnInitialize() Source/Runtime/Engine/Private/Actor.cpp:4249
AActor::PostActorCreated() Source/Runtime/Engine/Private/Actor.cpp:2094
AActor::RegisterAllComponents() Source/Runtime/Engine/Private/Actor.cpp:5941
AActor::PreInitializeComponents() Source/Runtime/Engine/Private/Actor.cpp:6556
AActor::InitializeComponents() Source/Runtime/Engine/Private/Actor.cpp:6325
AActor::PostInitializeComponents() Source/Runtime/Engine/Private/Actor.cpp:6544
AActor::DispatchBeginPlay() Source/Runtime/Engine/Private/Actor.cpp:4690
AActor::BeginPlay() Source/Runtime/Engine/Private/Actor.cpp:4753
AActor::RouteEndPlay() Source/Runtime/Engine/Private/Actor.cpp:3194
AActor::EndPlay() Source/Runtime/Engine/Private/Actor.cpp:3232
AActor::FinishSpawning() Source/Runtime/Engine/Private/Actor.cpp:4347
AActor::PostActorConstruction() Source/Runtime/Engine/Private/Actor.cpp:4403
AActor::RerunConstructionScripts() Source/Runtime/Engine/Private/ActorConstruction.cpp:252
AActor::ExecuteConstruction() Source/Runtime/Engine/Private/ActorConstruction.cpp:816
UActorComponent::OnComponentCreated() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:2155
UActorComponent::InitializeComponent() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:1589
UActorComponent::BeginPlay() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:1609
UActorComponent::EndPlay() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:1625
UGameplayStatics::BeginDeferredActorSpawnFromClass() Source/Runtime/Engine/Private/GameplayStatics.cpp:856
UGameplayStatics::FinishSpawningActor() Source/Runtime/Engine/Private/GameplayStatics.cpp:891
UWorld::Tick() Source/Runtime/Engine/Private/LevelTick.cpp:1477
FActorTickFunction::ExecuteTick() Source/Runtime/Engine/Private/Actor.cpp:370
AActor::Tick() Source/Runtime/Engine/Private/Actor.cpp:1971
FActorComponentTickFunction::ExecuteTick() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:1651
UActorComponent::TickComponent() Source/Runtime/Engine/Private/Components/ActorComponent.cpp:1838
EEndPlayReason (enum) Source/Runtime/Engine/Classes/Engine/EngineTypes.h:3428
AActor::Destroy() Source/Runtime/Engine/Private/Actor.cpp:5288
UWorld::DestroyActor() Source/Runtime/Engine/Private/LevelActor.cpp:838
AActor::Destroyed() Source/Runtime/Engine/Private/Actor.cpp:3284
相关推荐
2301_776508721 小时前
C++与机器学习框架
开发语言·c++·算法
ALex_zry2 小时前
现代C++设计模式实战:从AIDC项目看工业级代码架构
c++·设计模式·架构
Albertbreak2 小时前
STL容器内部实现剖析
开发语言·c++·算法
2301_795741792 小时前
模板编译期机器学习
开发语言·c++·算法
qq_416018722 小时前
模板错误消息优化
开发语言·c++·算法
ALex_zry2 小时前
C++高性能日志与监控系统设计
c++·unity·wpf
Sunshine for you2 小时前
C++中的对象池模式
开发语言·c++·算法
Nan_Shu_6142 小时前
学习:Cesium (4)
前端·学习
炽烈小老头2 小时前
【 每天学习一点算法 2026/03/25】在排序数组中查找元素的第一个和最后一个位置
学习·算法