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项目学习(零) 开篇&目录

相关推荐
摇滚侠9 分钟前
Spring Boot 3零基础教程,WEB 开发 通过配置类代码方式修改静态资源配置 笔记32
java·spring boot·笔记
电子云与长程纠缠20 分钟前
Blender入门学习01
学习·blender
qiuiuiu4131 小时前
正点原子RK3568学习日志12-注册字符设备
linux·开发语言·单片机·学习·ubuntu
聪明的笨猪猪2 小时前
Java JVM “内存(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
_dindong2 小时前
Linux网络编程:Socket编程TCP
linux·服务器·网络·笔记·学习·tcp/ip
金士顿2 小时前
ethercat网络拓扑详细学习
学习
知识分享小能手3 小时前
uni-app 入门学习教程,从入门到精通,uni-app组件 —— 知识点详解与实战案例(4)
前端·javascript·学习·微信小程序·小程序·前端框架·uni-app
wahkim3 小时前
Flutter 学习资源及视频
学习
摇滚侠3 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 属性优先级 行内写法 变量选择 笔记42
java·spring boot·笔记
摇滚侠3 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 总结 热部署 常用配置 笔记44
java·spring boot·笔记