栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

ue5 lyra分析,持续更新中

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ue5 lyra分析,持续更新中

问题1:

这个地图的worldsetting中并没有指定gamemode,那么游戏运行的时候角色的类型是怎么指定的呢?

 

有人说在projectsetting中有一个全局的gamemode

 但是这个角色的类型也不是真的运行起来角色的类型

 真的运行的时候角色的类型是 如上图所示

找一下吧,看看具体是在哪里设定的,过程是如何的。茫茫大海如何着手呢,我先在lyracharacter的构造函数打个断点看看

 从堆栈中找到一个有用的信息

 从图上看spawn的时候已经指定好了,而且这个函数是重载基类的方法,继续跟代码。

UClass* ALyraGameMode::GetDefaultPawnClassForController_Implementation(AController* InController)
{
	if (const ULyraPawnData* PawnData = GetPawnDataForController(InController))
	{
		if (PawnData->PawnClass)
		{
			return PawnData->PawnClass;
		}
	}

	return Super::GetDefaultPawnClassForController_Implementation(InController);
}

重载了父类 的方法,这里出现了ULyraPawnData这个数据类型,继续跟代码

 发现首先从gamestate上找到一个叫ULyraExperienceManagerComponent组件

从组件上获得一个ULyraExperienceDefinition数据类型的数据。

继续找

const ULyraExperienceDefinition* ULyraExperienceManagerComponent::GetCurrentExperienceChecked() const
{
	check(LoadState == ELyraExperienceLoadState::Loaded);
	check(CurrentExperience != nullptr);
	return CurrentExperience;
}

void ALyraGameMode::OnMatchAssignmentGiven(FPrimaryAssetId ExperienceId, const FString& ExperienceIdSource)
{
#if WITH_SERVER_CODE
	if (ExperienceId.IsValid())
	{
		UE_LOG(LogLyraExperience, Log, TEXT("Identified experience %s (Source: %s)"), *ExperienceId.ToString(), *ExperienceIdSource);

		ULyraExperienceManagerComponent* ExperienceComponent = GameState->FindComponentByClass();
		check(ExperienceComponent);
		ExperienceComponent->ServerSetCurrentExperience(ExperienceId);
	}
	else
	{
		UE_LOG(LogLyraExperience, Error, TEXT("Failed to identify experience, loading screen will stay up forever"));
	}
#endif
}
void ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()
{
	FPrimaryAssetId ExperienceId;
	FString ExperienceIdSource;

	// Precedence order (highest wins)
	//  - Matchmaking assignment (if present)
	//  - URL Options override
	//  - Developer Settings (PIE only)
	//  - Command Line override
	//  - World Settings
	//  - Default experience

	UWorld* World = GetWorld();

	if (!ExperienceId.IsValid() && UGameplayStatics::HasOption(OptionsString, TEXT("Experience")))
	{
		const FString ExperienceFromOptions = UGameplayStatics::ParseOption(OptionsString, TEXT("Experience"));
		ExperienceId = FPrimaryAssetId(FPrimaryAssetType(ULyraExperienceDefinition::StaticClass()->GetFName()), FName(*ExperienceFromOptions));
		ExperienceIdSource = TEXT("OptionsString");
	}

	if (!ExperienceId.IsValid() && World->IsPlayInEditor())
	{
		ExperienceId = GetDefault()->ExperienceOverride;
		ExperienceIdSource = TEXT("DeveloperSettings");
	}

	// see if the command line wants to set the experience
	if (!ExperienceId.IsValid())
	{
		FString ExperienceFromCommandLine;
		if (FParse::Value(FCommandLine::Get(), TEXT("Experience="), ExperienceFromCommandLine))
		{
			ExperienceId = FPrimaryAssetId::ParseTypeAndName(ExperienceFromCommandLine);
			ExperienceIdSource = TEXT("CommandLine");
		}
	}

	// see if the world settings has a default experience
	if (!ExperienceId.IsValid())
	{
		if (ALyraWorldSettings* TypedWorldSettings = Cast(GetWorldSettings()))
		{
			ExperienceId = TypedWorldSettings->GetDefaultGameplayExperience();
			ExperienceIdSource = TEXT("WorldSettings");
		}
	}

	ULyraAssetManager& AssetManager = ULyraAssetManager::Get();
	FAssetData Dummy;
	if (ExperienceId.IsValid() && !AssetManager.GetPrimaryAssetData(ExperienceId,  Dummy))
	{
		UE_LOG(LogLyraExperience, Error, TEXT("EXPERIENCE: Wanted to use %s but couldn't find it, falling back to the default)"), *ExperienceId.ToString());
		ExperienceId = FPrimaryAssetId();
	}

	// Final fallback to the default experience
	if (!ExperienceId.IsValid())
	{
		//@TODO: Pull this from a config setting or something
		ExperienceId = FPrimaryAssetId(FPrimaryAssetType("LyraExperienceDefinition"), FName("B_LyraDefaultExperience"));
		ExperienceIdSource = TEXT("Default");
	}

	OnMatchAssignmentGiven(ExperienceId, ExperienceIdSource);
}

void ALyraGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
	Super::InitGame(MapName, Options, ErrorMessage);

	//@TODO: Eventually only do this for PIE/auto
	GetWorld()->GetTimerManager().SetTimerForNextTick(this, &ThisClass::HandleMatchAssignmentIfNotExpectingOne);
}

从代码中我们发现 ,当gamemode初始化game的时候,下一帧就调用

HandleMatchAssignmentIfNotExpectingOne()这个方法

这个方法中有多个获得

ExperienceId的方法,不同的情况分别命中一个

而默认地图用的是最后一个

 对就是硬编码,写死的读取一个叫

B_LyraDefaultExperience的资源我们看看这个资源是什么

 

 真是绕啊,不过lyra也遵循了数据驱动的原则,这些UPrimaryDataAsset就是数据配置。

--------------------------------------------------------------------------------------------------------

问题2:我们进这个地图会是什么流程

首先看看这个control 特效这一疙瘩是怎么生成的。

刚开始默认的地图中,有一个这个蓝图actor,里面有逻辑。

 在beginplay里面获得了所有类型是LyraUserFacingExperienceDefinition的资源primary asset id

然后有几个LyraUserFacingExperienceDefinition这个就生成几个B_TeleportToUserFacingExperience

 我们先看看LyraUserFacingExperienceDefinition这个都定义了什么

 通过上图可以看到最重要的是定义了那张地图和一个数据这个数据定义了角色是哪个还有各种gamefeature的 action

生成B_TeleportToUserFacingExperience的时候把对应的LyraUserFacingExperienceDefinition带进去

 

 在B_TeleportToUserFacingExperience里面有一个碰撞体,看看碰撞方法里面的逻辑

 当一个角色碰撞到这个粒子特效的时候

 1是生成了request

 

 

然后

我们一直用的是standalong模式所以目前的流程就是server的流程

从外面向里面分析先到这里,我们从里面向外面分析,最后肯定会汇合到这里

我们断点到这里

 同一个函数,control这个地图进的是这个,并且把experienceid得到了

我们看看 这个optionsString是怎么赋值的

看看对上了,就是servertravel的时候把nextmap记录下来

然后在

UEngine::TickWorldTravel

中判断是不是空,非空就loadmap。

---------------------------------------------------------------------------------------------------

问题3:lyra的gamefeature  and  ULyraExperienceDefinition中的actions

在看 lyra的过程中你会发现:

既有正常的gamefeature的action

又有在ULyraExperienceDefinition中定义的action

感觉好乱

 先看正常的gamefeature

lyra工程中也有继承

UDefaultGameFeaturesProjectPolicies

 而来的

ULyraGameFeaturePolicy

 但是看了源码,并没有对plugin里面的gamefeature做策略性的加载,所以plugin里面的gamefeature会随着gamefeaturesubsystem的创建和init方法,而导入到内存中,并且自动active,所以gamefeaturedata里面设置的action都会自动运行。

而ULyraExperienceDefinition中定义的action是手动调用的

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901086.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号