目录
纯个人笔记,有错误欢迎指正,学习阶段基本看到不会的就写一写,最后有时间会梳理整体结构
先看完了官方的演讲
1 地图加载流程
1.1 默认Experience的加载
这里先不从GameInstance开始,中间的CommonUser等流程暂时不谈(有点多暂时不想看0w0),编辑器默认地图L_DefaultEditorOverview中没有重载游戏模式,所以用项目默认的B_LyraGameMode。
ALyraGameMode::InitGame()
// Wait for the next frame to give time to initialize startup settings
GetWorld()->GetTimerManager().SetTimerForNextTick(this, &ThisClass::HandleMatchAssignmentIfNotExpectingOne);
可见逻辑转到了ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()
(这里走的默认分支)
void ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()
{
...
ExperienceId = FPrimaryAssetId(FPrimaryAssetType("LyraExperienceDefinition"), FName("B_LyraDefaultExperience"));
ExperienceIdSource = TEXT("Default");
...
OnMatchAssignmentGiven(ExperienceId, ExperienceIdSource);
}
之后的调用栈大概是
OnMatchAssignmentGiven(ExperienceId, ExperienceIdSource)->
void ULyraExperienceManagerComponent::SetCurrentExperience(ExperienceId)->
void ULyraExperienceManagerComponent::StartExperienceLoad()->
void ULyraExperienceManagerComponent::OnExperienceLoadComplete()
过程大体是设置当前ExperienceId,异步加载Experience相关资源,调用加载完成的回调.
OnExperienceLoadComplete()函数收集GameFeaturePluginURL,最终调用
UGameFeaturesSubsystem::Get().
LoadAndActivateGameFeaturePlugin(PluginURL,
FGameFeaturePluginLoadComplete::CreateUObject(this,
&ThisClass::OnGameFeaturePluginLoadComplete));
触发默认Feature的Action
这里记录一下几个Action函数的调用顺序, 防止我忘了
在这个函数中:
void ULyraExperienceManagerComponent::OnExperienceFullLoadCompleted()
ActivateListOfActions的定义
auto ActivateListOfActions = [&Context](const TArray<UGameFeatureAction*>& ActionList)
{
for (UGameFeatureAction* Action : ActionList)
{
if (Action != nullptr)
{
//@TODO: The fact that these don't take a world are potentially problematic in client-server PIE
// The current behavior matches systems like gameplay tags where loading and registering apply to the entire process,
// but actually applying the results to actors is restricted to a specific world
Action->OnGameFeatureRegistering();
Action->OnGameFeatureLoading();
Action->OnGameFeatureActivating(Context);
}
}
};
逐一调用顺序
自己的Actions先调用,再遍历调用ActionSets
ActivateListOfActions(CurrentExperience->Actions);
for (const TObjectPtr<ULyraExperienceActionSet>& ActionSet : CurrentExperience->ActionSets)
{
if (ActionSet != nullptr)
{
ActivateListOfActions(ActionSet->Actions);
}
}
三个多播顺序
OnExperienceLoaded_HighPriority.Broadcast(CurrentExperience);
OnExperienceLoaded_HighPriority.Clear();
OnExperienceLoaded.Broadcast(CurrentExperience);
OnExperienceLoaded.Clear();
OnExperienceLoaded_LowPriority.Broadcast(CurrentExperience);
OnExperienceLoaded_LowPriority.Clear();
1.2 加载角色
B_LyraDefaultExperience中:
SimplePawnData:
可以发现通过这个就找到了创建的金属Pawn,而不是GameMode中的角色类(是其蓝图子类)
但是为什么这里的配置能够生效呢?
因为ALyraGameMode重写了这个实现:
APawn* ALyraGameMode::SpawnDefaultPawnAtTransform_Implementation(AController* NewPlayer, const FTransform& SpawnTransform){
...
if (UClass* PawnClass = GetDefaultPawnClassForController(NewPlayer))
{
if (APawn* SpawnedPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnInfo))
...
}
UClass* ALyraGameMode::GetDefaultPawnClassForController_Implementation(AController* InController)
{
if (const ULyraPawnData* PawnData = GetPawnDataForController(InController))
{
if (PawnData->PawnClass)
{
return PawnData->PawnClass;
}
}
...
}
const ULyraPawnData* ALyraGameMode::GetPawnDataForController(const AController* InController) const
{
...
return Experience->DefaultPawnData;
...
}
1.3 加载场景中的几个传送点
由场景中这个Actor控制:
生成逻辑没什么该注意的,注意生成时传入了LyraUserfacingExperienceDefinition类型的变量,Widget信息都是根据这个配置的。
主要看加载地图:
可见信息都在LyraUserfacingExperienceDefinition中,例如这个下边这个,可以看到
要去的地图信息都有。
2 几个内建类的笔记
2.1 UDataAsset
刚拿到项目无从下手,就去看了启动默认地图L_LyraFrontEnd,没有重载GameMode,即用的项目设置的B_LyraGameMode,暂时先不看GameMode,然后基于演讲去看了DefaultGameplayExperience,一路看过去
B_LyraFrontEnd_Experience->
ULyraExperienceDefinition->
UPrimaryDataAsset->
UDataAsset->
UObject
这时候我发现我对DataAsset没什么了解,只好先去学习一下:
UCLASS(abstract, MinimalAPI, Meta = (LoadBehavior = "LazyOnDemand"))
class UDataAsset : public UObject
abstract:
MinimalAPI没太看懂,大概是优化编译相关的:
LoadBehavior
UPrimaryDataAsset:
UE5–PrimaryDataAsset资产包更新UpdateAssetBundleData源码分析
看完这几篇后我的理解这个类就是数据资产。
2.2 UAssetManager
暂时停留在使用层理解。
UE5 AssetManager类使用详解
参考文章:
UE5 Lyra项目学习(零) 开篇&目录