问题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<ULyraExperienceManagerComponent>();
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<ULyraDeveloperSettings>()->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<ALyraWorldSettings>(GetWorldSettings()))
{
ExperienceId = TypedWorldSettings->GetDefaultGameplayExperience();
ExperienceIdSource = TEXT("WorldSettings");
}
}
ULyraAssetManager& AssetManager = ULyraAssetManager::Get();
FAssetData Dummy;

本文详细探讨了UE5 Lyra项目中角色类型设定的查找过程,从worldsettings到gamestate,揭示了角色类型设定的细节。此外,分析了地图进入流程,特别是B_TeleportToUserFacingExperience的生成逻辑。还研究了gamefeature和ULyraExperienceDefinition中的actions,以及UI交互,如ESC退出逻辑和加载屏幕的显示控制。通过对项目设置、蓝图和C++代码的调查,揭示了这些机制的工作原理。


被折叠的 条评论
为什么被折叠?



