UE4 ActionRPG学习记录1-游戏加载

游戏的加载流程
先看下官方文档的图
原图链接:https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Framework/GameFlow/
事件的一般顺序为初始化引擎、创建并初始化 GameInstance、加载关卡,最后开始游戏。事件的一般顺序为初始化引擎、创建并初始化 GameInstance、加载关卡,最后开始游戏。事件的一般顺序为初始化引擎、创建并初始化 GameInstance、加载关卡,最后开始游戏。
GameEngine::Init
先看GameEngin::Init`

//加载并应用用户游戏设置
GetGameUserSettings()->LoadSettings();
GetGameUserSettings()->ApplyNonResolutionSettings();
//创建游戏实例。对于GameEngine,这应该是唯一创建的GameInstance。
{
	FSoftClassPath GameInstanceClassName = GetDefault<UGameMapsSettings>()->GameInstanceClass;
	UClass* GameInstanceClass = (GameInstanceClassName.IsValid() ? LoadObject<UClass>(NULL, *GameInstanceClassName.ToString()) : UGameInstance::StaticClass());
	if (GameInstanceClass == nullptr)
	{
		UE_LOG(LogEngine, Error, TEXT("Unable to load GameInstance Class '%s'. Falling back to generic UGameInstance."), *GameInstanceClassName.ToString());
		GameInstanceClass = UGameInstance::StaticClass();
	}
	GameInstance = NewObject<UGameInstance>(this, GameInstanceClass);
	GameInstance->InitializeStandalone();
}

`可以看到,应用了用户设置之后,就看上创建了GameInstance;接着调用了GameInstance->InitializeStandalone();
继续接着看InitializeStandalone()里面干了什么了。

void UGameInstance::InitializeStandalone(const FName InPackageName, UPackage* InWorldPackage)
{
	//创建世界上下文。这应该是为这个游戏实例创建的唯一WorldContext。
	WorldContext = &GetEngine()->CreateNewWorldContext(EWorldType::Game);
	WorldContext->OwningGameInstance = this;
	//在独立的环境中,从一开始就创建一个虚拟世界,以避免在LoadMap使我们真正的世界到来之前没有世界的问题
	UWorld* DummyWorld = UWorld::CreateWorld(EWorldType::Game, false, InPackageName, InWorldPackage);
	DummyWorld->SetGameInstance(this);
	WorldContext->SetCurrentWorld(DummyWorld);
	Init();
}
void UWorld::InitializeNewWorld(const InitializationValues IVS)
{
	if (!IVS.bTransactional)
	{
		ClearFlags(RF_Transactional);
	}

	PersistentLevel = NewObject<ULevel>(this, TEXT("PersistentLevel"));
	PersistentLevel->Initialize(FURL(nullptr));
	PersistentLevel->Model = NewObject<UModel>(PersistentLevel);
	PersistentLevel->Model->Initialize(nullptr, 1);
	PersistentLevel->OwningWorld = this;

	// Create the WorldInfo actor.
	FActorSpawnParameters SpawnInfo; 
}
void UGameInstance::Init()
{
	ReceiveInit();

	if (!IsRunningCommandlet())
	{
		UClass* SpawnClass = GetOnlineSessionClass();
		OnlineSession = NewObject<UOnlineSession>(this, SpawnClass);
		if (OnlineSession)
		{
			OnlineSession->RegisterOnlineDelegates();
		}

		if (!IsDedicatedServerInstance())
		{
			TSharedPtr<GenericApplication> App = FSlateApplication::Get().GetPlatformApplication();
			if (App.IsValid())
			{
				App->RegisterConsoleCommandListener(GenericApplication::FOnConsoleCommandListener::CreateUObject(this, &ThisClass::OnConsoleInput));
			}
		}

		FNetDelegates::OnReceivedNetworkEncryptionToken.BindUObject(this, &ThisClass::ReceivedNetworkEncryptionToken);
		FNetDelegates::OnReceivedNetworkEncryptionAck.BindUObject(this, &ThisClass::ReceivedNetworkEncryptionAck);
	}

	SubsystemCollection.Initialize(this);
}

可以看到,创建了WorldContext 和 DummyWorld;
UWorld::InitializeNewWorld里面创建了关卡
还创建了了在线会话。

下面继续看World::BeginPlay

void UWorld::BeginPlay()
{
	AGameModeBase* const GameMode = GetAuthGameMode();
	if (GameMode)
	{
		GameMode->StartPlay();
		if (GetAISystem())
		{
			GetAISystem()->StartPlay();
		}
	}

	OnWorldBeginPlay.Broadcast();
}

开始了GameMode::StartPlay();

void AGameModeBase::StartPlay()
{
	GameState->HandleBeginPlay();
}
void AGameStateBase::HandleBeginPlay()
{
	bReplicatedHasBegunPlay = true;

	GetWorldSettings()->NotifyBeginPlay();
	GetWorldSettings()->NotifyMatchStarted();
}
void AWorldSettings::NotifyBeginPlay()
{
	UWorld* World = GetWorld();
	if (!World->bBegunPlay)
	{
		for (FActorIterator It(World); It; ++It)
		{
			SCOPE_CYCLE_COUNTER(STAT_ActorBeginPlay);
			const bool bFromLevelLoad = true;
			It->DispatchBeginPlay(bFromLevelLoad);
		}

		World->bBegunPlay = true;
	}
}
void AActor::DispatchBeginPlay(bool bFromLevelStreaming)
{
	UWorld* World = (!HasActorBegunPlay() && !IsPendingKill() ? GetWorld() : nullptr);

	if (World)
	{
		ensureMsgf(ActorHasBegunPlay == EActorBeginPlayState::HasNotBegunPlay, TEXT("BeginPlay was called on actor %s which was in state %d"), *GetPathName(), (int32)ActorHasBegunPlay);
		const uint32 CurrentCallDepth = BeginPlayCallDepth++;

		bActorBeginningPlayFromLevelStreaming = bFromLevelStreaming;
		ActorHasBegunPlay = EActorBeginPlayState::BeginningPlay;
		BeginPlay();

		ensure(BeginPlayCallDepth - 1 == CurrentCallDepth);
		BeginPlayCallDepth = CurrentCallDepth;

		if (bActorWantsDestroyDuringBeginPlay)
		{
			// Pass true for bNetForce as either it doesn't matter or it was true the first time to even 
			// get to the point we set bActorWantsDestroyDuringBeginPlay to true
			World->DestroyActor(this, true); 
		}
		
		if (!IsPendingKill())
		{
			// Initialize overlap state
			UpdateInitialOverlaps(bFromLevelStreaming);
		}

		bActorBeginningPlayFromLevelStreaming = false;
	}
}

从以上源码可以看出,最后面调用Actor::BeginPlay.
现在回到我们的ActionRPG.
在这里插入图片描述
在这里插入图片描述
现在就看BP_MainMenuGameMode里面的流程。
在这里插入图片描述
这个就比较简单了,就是打开了WB_Title这个面板。

点击面板中的开始游戏。
在这里插入图片描述
可以看到移除所有面板,播放一个加载界面,就开始打开ActionRPG主场景了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值