UE4实现断线重连功能

断线重连的整体逻辑是 设备离线后,根据需要决定是否保留pawn,还是设备重连后再重新生成一个,然后是断线重连时的验证方式,最后是playerstate重连后的属性保留

  1. 重载Playercontroller的PawnLeavingGame,这里是设备断线后,不会删除pawn,根据自己的需求决定是否需要修改,如果不需要保存pawn,没有必要重载该函数。

    void AMVNControllerBase::PawnLeavingGame()
    {
    if (GetPawn() != NULL)
    {
    //GetPawn()->Destroy();
    //SetPawn(NULL);
    }
    }

2.如果要保留pawn的话,可以重载GameMode的AddInactivePlayer,这个函数原本是保留断线的playerstate的,如果也要保留pawn的话,可以在这个函数里参照保留PlayerState的方式,保存pawn,如果不需要保存pawn,没有必要重载该函数。

复制代码
void AVTTSGameModeBase::AddInactivePlayer(APlayerState* PlayerState, APlayerController* PC)
{
	check(PlayerState)
		UWorld* LocalWorld = GetWorld();
	// don't store if it's an old PlayerState from the previous level or if it's a spectator... or if we are shutting down
	if (!PlayerState->IsFromPreviousLevel() && !MustSpectate(PC) && !LocalWorld->bIsTearingDown)
	{
		APlayerState* const NewPlayerState = PlayerState->Duplicate();
		APawn* PolicePawn = PC->GetPawn();
		if (NewPlayerState && PolicePawn)
		{
			// Side effect of Duplicate() adding PlayerState to PlayerArray (see APlayerState::PostInitializeComponents)
			GameState->RemovePlayerState(NewPlayerState);

			// make PlayerState inactive
			NewPlayerState->SetReplicates(false);

			// delete after some time
			NewPlayerState->SetLifeSpan(InactivePlayerStateLifeSpan);
			//设置自动删除的时间
			PolicePawn->SetLifeSpan(InactivePlayerStateLifeSpan);
			// On console, we have to check the unique net id as network address isn't valid
			const bool bIsConsole = !PLATFORM_DESKTOP;
			// Assume valid unique ids means comparison should be via this method
			const bool bHasValidUniqueId = NewPlayerState->GetUniqueId().IsValid();
			// Don't accidentally compare empty network addresses (already issue with two clients on same machine during development)
			const bool bHasValidNetworkAddress = !NewPlayerState->SavedNetworkAddress.IsEmpty();
			const bool bUseUniqueIdCheck = bIsConsole || bHasValidUniqueId;

			// make sure no duplicates
			for (int32 Idx = 0; Idx < InactivePlayerArray.Num(); ++Idx)
			{
				APlayerState* const CurrentPlayerState = InactivePlayerArray[Idx];
				if ((CurrentPlayerState == nullptr) || CurrentPlayerState->IsPendingKill())
				{
					// already destroyed, just remove it
					InactivePlayerArray.RemoveAt(Idx, 1);
					InactivePawnArray.RemoveAt(Idx, 1);
					Idx--;
				}
				else if ((!bUseUniqueIdCheck && bHasValidNetworkAddress && (CurrentPlayerState->SavedNetworkAddress == NewPlayerState->SavedNetworkAddress))
					|| (bUseUniqueIdCheck && (CurrentPlayerState->GetUniqueId() == NewPlayerState->GetUniqueId())))
				{
					// destroy the playerstate, then remove it from the tracking
					CurrentPlayerState->Destroy();
					InactivePlayerArray.RemoveAt(Idx, 1);
					InactivePawnArray.RemoveAt(Idx, 1);  //保存角色
					Idx--;
				}
			}
			InactivePlayerArray.Add(NewPlayerState);
			InactivePawnArray.Add(PolicePawn);
			// make sure we dont go over the maximum number of inactive players allowed
			if (InactivePlayerArray.Num() > MaxInactivePlayers)
			{
				int32 const NumToRemove = InactivePlayerArray.Num() - MaxInactivePlayers;

				// destroy the extra inactive players
				for (int Idx = 0; Idx < NumToRemove; ++Idx)
				{
					APlayerState* const PS = InactivePlayerArray[Idx];
					if (PS != nullptr)
					{
						PS->Destroy();
					}
				}

				// and then remove them from the tracking array
				InactivePlayerArray.RemoveAt(0, NumToRemove);
				InactivePawnArray.RemoveAt(0, NumToRemove);
			}
		}
	}
}
  1. 同理如果需要重新获得之前保留的pawn的话,重载gamemode的restartPlayerAtPlayerStart,默认的话是直接生成新的pawn,如果你想直接使用就的pawn修改响应的逻辑
  2. 重载时设备的验证,GameMode的FindInactivePlayer函数,默认设备重连时会比较网络的UniqueId,如果一致那么会复制原本的设备的playerstate数据,但是如果你的客户端设备经过重启的话,是会识别成新的客户端,所以根据需要自己去决定是否修改验证方式。
  3. 重载PlayerState的CopyProperties,将你自定义的变量进行重新复制

以上就是断线重连基本的涉及的函数了,这一切的前提是gamemode必须继承自AGameMode,然后如果你没有保留pawn,或者自己验证重新登录逻辑的话,只需要修改第5条对应的内容就可以实现断线重连了

相关推荐
两个人的幸福11 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
zzzzzz31011 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
BingoGo13 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack13 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
大树8814 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
小宇宙Zz14 天前
Maven依赖冲突
java·服务器·maven
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip14 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua