五、Actor的基础知识
1.Actor的生命周期:
1.Actor的创建
a.从磁盘加载,适用于关卡中的Actor创建。
创建流程:1.LoadMap或AddToWorld被调用
2.从磁盘中加载Actor
3.执行PostLoad,可执行自定义版本化和修复操作。
4.InitializeActorsForPlay:初始化Actor
5.为未初始化的 Actor 执行 RouteActorInitialize
6.初始化组件:PreInitializeComponents - 在 Actor 的组件上调用 InitializeComponent 之前进行调用
InitializeComponent - Actor 上定义的每个组件的创建辅助函数。
PostInitializeComponents - Actor 的组件初始化后调用
7.BeginPlay - 关卡开始后调用
b.从编辑器中复制。
创建流程:1.编辑器中的 Actor 被复制到新世界场景中
2.PostDuplicate 被调用
3.InitializeActorsForPlay:初始化Actor
4.为未初始化的 Actor 执行 RouteActorInitialize
5.初始化组件:同上
6.BeginPlay - 关卡开始后调用
c.实例Actor
创建流程:1.SpawnActor 被调用
2.PostSpawnInitialize
3.PostActorCreated 构建函数类行为在此发生。PostActorCreated 与 PostLoad 互斥。
4.ExecuteConstruction:OnConstruction - Actor 的构建。蓝图 Actor 的组件在此处创建,蓝图变量在此处初始化
5.PostActorConstruction
6.初始化组件:同上
7.OnActorSpawned 在 UWorld 上播放
8.BeginPlay - 关卡开始后调用
d.延迟生成,将任意属性设为“Expose on Spawn”即可延迟 Actor 的生成。
创建流程:1.SpawnActorDeferred - 生成程序化 Actor,在蓝图构建脚本之前进行额外设置
2.PostSpawnInitialize
3.PostActorCreated 构建函数类行为在此发生。PostActorCreated 与 PostLoad 互斥。
4.通过一个有效但不完整的 Actor 实例设置/调用多个“初始化函数”
5.FinishSpawningActor -调用后对 Actor 进行最终化,在 Spawn Actor 行中选取 ExecuteConstruction。
6.ExecuteConstruction:OnConstruction - Actor 的构建。蓝图 Actor 的组件在此处创建,蓝图变量在此处初始化
7.PostActorConstruction
8.初始化组件:同上
9.OnActorSpawned 在 UWorld 上播放
10.BeginPlay - 关卡开始后调用
2.Actor的销毁
销毁流程:
a.EndPlay - 在数个地方调用,保证 Actor 的生命走向终点。调用EndPlay的全部情形:
1.对 Destroy 显式调用
2.Play in Editor 终结
3.关卡过渡(无缝行程或加载地图) 包含 Actor 的流关卡被卸载
4.Actor 的生命期已过
5.应用程序关闭(全部 Actor 被销毁)
b.无论这些情形出现的方式如何,Actor 都将被标记为 RF_PendingKill,因此在下个垃圾回收周期中它将被解除分配。
c.一个对象被标记待销毁的一段时间后,垃圾回收会将其从内存中实际移除,释放其使用的资源。销毁过程:
1.BeginDestroy - 对象可利用此机会释放内存并处理其他多线程资源(即为图像线程代理对象)。
2.IsReadyForFinishDestroy - 垃圾回收过程将调用此函数,以确定对象是否可被永久解除分配。
3.FinishDestroy - 最后对象将被销毁,这是释放内部数据结构的另一个机会。
2.组件:
1.组件是一种特殊类型的对象,作为Actor中的子对象使用。
2.ActorComponent 是组件的基础类,定义可被添加到不同类型 Actor 的重复使用行为。
3.为使ActorComponent每帧更新并对场景产生影响,它们必须和场景进行注册。调用UActorComponent::RegisterComponent()即可执行注册。
4.也可取消ActorComponent的注册,避免它们被更新、模拟,或渲染。调用UActorComponent::UnregisterComponent()即可取消组件注册。
5.ActorComponent可通过其TickComponent()函数进行每帧更新。
3.生成Actor:
1.创建一个新的Actor示例的过程称为生成。生成Actors的过程是使用UWorld::SpawnActor()函数完成的。
2.SpawnActor类的结构如下:
AActor* UWorld::SpawnActor
(
UClass* Class,指出要生成的Actor的类。
FName InName,用作生成的Actor的名称。
FVector const* Location,用作生成的Actor的初始位置。
FRotator const* Rotation,用作生成的Actor的初始旋转度。
AActor* Template,用作生成的Actor时使用的模板。所生成的Actor将使用模板Actor的属性值进行初始化。
bool bNoCollisionFail,决定生成的Actor是否执行碰撞测试。如果为true,则在生成Actor时不进行碰撞测试。
bool bRemoteOwned,
AActor* Owner,拥有所生成的Actor的AActor。
APawn* Instigator,导致所生成的Actor施加伤害的挑衅者。
bool bNoFail,决定了如果某些条件不满足,生成Actor是否失败。
ULevel* OverrideLevel,指定生成Actor的Ulevel,也就是Actor的外部容器。
bool bDeferConstruction,决定是否运行构建脚本 。
)
3.SpawnActor()函数的用法:AKAsset* SpawnedActor1 = (AKAsset*) GetWorld()->SpawnActor(AKAsset::StaticClass(), NAME_None, &Location);
4.Actor Ticking:
1.Tick指的是以规则间隔(常为每帧一次)在一个actor或组件上运行一段代码或蓝图脚本。
2.Actors和组件可设为每帧tick,也可设为以最低时间间隔tick,或完全不tick。此外,它们可在引擎每帧更新循环中的不同阶段被合并为组;也可接受单独指令,等待特定tick完成后再开始。
3.Tick 组可在代码或蓝图中指定。每个tick组将完成对指定的每个actor和组件的tick,然后再开始下一个tick组。
4.可拥有游戏性的tick组有:
a.TG_PrePhysics:Actor与物理对象(包括基于物理的附着物)进行交互时使用的tick组。
此tick中的物理模拟数据属于上一帧 — 也就是上一帧渲染到屏幕上的数据。
b.TG_DuringPhysics:此tick组只推荐用于无视物理数据或允许一帧偏差的逻辑。
c.TG_PostPhysics:此组可用于武器或运动追踪。渲染此帧时所有物理对象将位于它们的最终位置。
d.TG_PostUpdateWork:此组可将最靠后的信息送入粒子系统。
5.在BeginPlay中,actor将向引擎注册其主tick函数和其组件的tick函数。Actor的tick函数可通过PrimaryActorTick成员设为在特定tick组中运行,或完全禁用。
代码如下:
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bTickEvenWhenPaused = true;
PrimaryActorTick.TickGroup = TG_PrePhysics;
组件Tick函数代码如下:
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bTickEvenWhenPaused = true;
PrimaryComponentTick.TickGroup = TG_PrePhysics;
6.注意:PrimaryActorTick使用Actor的Tick()函数,而PrimaryComponentTick使用ActorComponent的TickComponent()函数。