Lyra学习笔记1地图角色加载流程

目录

  • [1 地图加载流程](#1 地图加载流程)
    • [1.1 默认Experience的加载](#1.1 默认Experience的加载)
    • [1.2 加载角色](#1.2 加载角色)
    • [1.3 加载场景中的几个传送点](#1.3 加载场景中的几个传送点)
  • [2 几个内建类的笔记](#2 几个内建类的笔记)
    • [2.1 UDataAsset](#2.1 UDataAsset)
    • [2.2 UAssetManager](#2.2 UAssetManager)

纯个人笔记,有错误欢迎指正,学习阶段基本看到不会的就写一写,最后有时间会梳理整体结构
先看完了官方的演讲

1 地图加载流程

1.1 默认Experience的加载

这里先不从GameInstance开始,中间的CommonUser等流程暂时不谈(有点多暂时不想看0w0),编辑器默认地图L_DefaultEditorOverview中没有重载游戏模式,所以用项目默认的B_LyraGameMode。

ALyraGameMode::InitGame()

cpp 复制代码
// Wait for the next frame to give time to initialize startup settings
GetWorld()->GetTimerManager().SetTimerForNextTick(this, &ThisClass::HandleMatchAssignmentIfNotExpectingOne);

可见逻辑转到了ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()

(这里走的默认分支)

cpp 复制代码
void ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()
{
	...
	ExperienceId = FPrimaryAssetId(FPrimaryAssetType("LyraExperienceDefinition"), FName("B_LyraDefaultExperience"));
	ExperienceIdSource = TEXT("Default");
	...
	OnMatchAssignmentGiven(ExperienceId, ExperienceIdSource);
}

之后的调用栈大概是

cpp 复制代码
OnMatchAssignmentGiven(ExperienceId, ExperienceIdSource)->
void ULyraExperienceManagerComponent::SetCurrentExperience(ExperienceId)->
void ULyraExperienceManagerComponent::StartExperienceLoad()->
void ULyraExperienceManagerComponent::OnExperienceLoadComplete()

过程大体是设置当前ExperienceId,异步加载Experience相关资源,调用加载完成的回调.

OnExperienceLoadComplete()函数收集GameFeaturePluginURL,最终调用

cpp 复制代码
UGameFeaturesSubsystem::Get().
LoadAndActivateGameFeaturePlugin(PluginURL,  
FGameFeaturePluginLoadComplete::CreateUObject(this, 
&ThisClass::OnGameFeaturePluginLoadComplete));

触发默认Feature的Action

这里记录一下几个Action函数的调用顺序, 防止我忘了
在这个函数中:
void ULyraExperienceManagerComponent::OnExperienceFullLoadCompleted()

ActivateListOfActions的定义

cpp 复制代码
	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

cpp 复制代码
ActivateListOfActions(CurrentExperience->Actions);
	for (const TObjectPtr<ULyraExperienceActionSet>& ActionSet : CurrentExperience->ActionSets)
	{
		if (ActionSet != nullptr)
		{
			ActivateListOfActions(ActionSet->Actions);
		}
	}

三个多播顺序

cpp 复制代码
	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重写了这个实现:

cpp 复制代码
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没什么了解,只好先去学习一下:

cpp 复制代码
UCLASS(abstract, MinimalAPI, Meta = (LoadBehavior = "LazyOnDemand"))
class UDataAsset : public UObject

abstract:

MinimalAPI没太看懂,大概是优化编译相关的:

LoadBehavior

UPrimaryDataAsset:
UE5--PrimaryDataAsset资产包更新UpdateAssetBundleData源码分析
看完这几篇后我的理解这个类就是数据资产。


2.2 UAssetManager

暂时停留在使用层理解。
UE5 AssetManager类使用详解


参考文章:
UE5 Lyra项目学习(零) 开篇&目录

相关推荐
龙湾开发20 分钟前
C++ vscode配置c++开发环境
开发语言·c++·笔记·vscode·学习
爱学习的小邓同学35 分钟前
C++ --- string
c++·笔记
岂是尔等觊觎1 小时前
PCB设计教程【入门篇】——电路分析基础-元件数据手册
经验分享·笔记·嵌入式硬件·学习·pcb工艺
jerry6091 小时前
蒙特卡洛树搜索 (MCTS)
人工智能·笔记·深度学习·学习·算法·机器学习
韩明君1 小时前
前端学习笔记——Promis.All
前端·笔记·学习
江畔柳前堤2 小时前
PyQt学习系列11-综合项目:多语言文件管理器
开发语言·网络·python·学习·django·pyqt
爱凤的小光2 小时前
Opencv常见学习链接(待分类补充)
人工智能·opencv·学习
-一杯为品-3 小时前
【强化学习】#7 基于表格型方法的规划和学习
学习·强化学习
真的想上岸啊3 小时前
学习STC51单片机14(芯片为STC89C52RC)
单片机·嵌入式硬件·学习
hello1114-4 小时前
Redis学习打卡-Day6-Redis 高可用(上)
数据库·redis·学习