UE多人游戏c++随笔(返回菜单功能+RPC+委托绑定+编程逻辑)

196.Player Bookkeeping

今天的视频有点绕,脑子转了好久,所以详细记录一下编程逻辑,供日后参考
视频
功能:
我们需要播放离开的动画

掉落武器

对最高分的选手进行追踪

server离开游戏时,所有玩家全部踢掉

client离开游戏,就自己滚蛋

请添加图片描述
请添加图片描述

头文件

我们在BlasterCharacter的新建变量,用于判断角色是否是离开游戏的状态变量

bool bLeftGame = false;

同时我们需要声明一个委托

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnLeftGame);

并且在private里定义委托变量用于绑定

FOnLeftGame OnLeftGame;

我们还要在BlasterCharacter新建serverRPC,以帮助client端玩家通知server断开连接

UFUNCTION(Server,Reliable)
void ServerLeaveGame();

我们继续在BlasterGameMode.cpp新建方法

void PlayerLeftGame(class ABlasterPlayerState* PlayerLeaving);

我们原先BlasterCharacter的Elim()和MulticastElim()方法需要添加Character的bLeftGame进行判断,所以重构

void Elim(bool bPlayerLeftGame);
UFUNCTION(NetMulticast, Reliable)
void MulticastElim(bool bPlayerLeftGame);

请添加图片描述

cpp文件

然后我们在ServerLeaveGame中调用BlasterGameMode的方法PlayerLeftGame

void ABlasterCharacter::ServerLeaveGame_Implementation()
{
	ABlasterGameMode* BlasterGameMode = GetWorld()->GetAuthGameMode<ABlasterGameMode>();
	BlasterPlayerState = BlasterPlayerState == nullptr ? GetPlayerState<ABlasterPlayerState>() : BlasterPlayerState;
	if (BlasterGameMode && BlasterPlayerState)
	{
		BlasterGameMode->PlayerLeftGame(BlasterPlayerState);
	}
}

我们在MulticastElim方法添加,这样我们可以在计时器结束后,进行bLeftGame判定,以取消重生玩家

bLeftGame = bPlayerLeftGame; //最重要

然后我们在ElimTimerFinished()结束后,判断玩家是否离开游戏,离开的话调用委托OnLeftGame.Broadcast()

void ABlasterCharacter::ElimTimerFinished()
{
	ABlasterGameMode* BlasterGameMode = GetWorld()->GetAuthGameMode<ABlasterGameMode>();
	if (BlasterGameMode && !bLeftGame)
	{
		BlasterGameMode->RequestRespawn(this, Controller);
	}
	if (bLeftGame && IsLocallyControlled())
	{
		OnLeftGame.Broadcast();
	}
}

我们的playerGameMode也需要知道playerstate以对最高分玩家进行更新

请添加图片描述

所以我们在BlasterCharacter里开始传递数值

请添加图片描述

GameMode我们重构PlayerLeftGame方法,添加参数

void PlayerLeftGame(class ABlasterPlayerState* PlayerLeaving);

然后我们写PlayerLeftGame函数

void ABlasterGameMode::PlayerLeftGame(ABlasterPlayerState* PlayerLeaving)
{
	//调用elim,传递true值进去
	if (PlayerLeaving == nullptr) return;
	ABlasterGameState* BlasterGameState = GetGameState<ABlasterGameState>();
	if (BlasterGameState && BlasterGameState->TopScoringPlayers.Contains(PlayerLeaving))
	{
		BlasterGameState->TopScoringPlayers.Remove(PlayerLeaving);
	}
	ABlasterCharacter* CharacterLeaving = Cast<ABlasterCharacter>(PlayerLeaving->GetPawn());
	if (CharacterLeaving)
	{
		CharacterLeaving->Elim(true);
	}
}

目前所有代码执行逻辑是,我们BlasterCharacter的ServerLeaveGame执行,然后我们进入到BlasterGameMode,调用BlasterCharacter的Elim()方法,Elim()调用MulticastElim网络多播,设置

bLeftGame = true,在计时器结束后,ElimTimerFinished()判断是否离开游戏,然后播放委托OnLeftGame.Broadcast()

我们需要在ReturnToMainMenu进行委托函数构造

首先是ReturnButtonClicked()

我们要对BlasterCharacter进行判断,通过controller获取pawn属性。当他离开了游戏,BlasterCharacter为Nullptr,就重新设置button为true状态,否则serverLeaveGame(),这个方式是serverRPC

void UReturnToMainMenu::ReturnButtonClicked()
{
	ReturnButton->SetIsEnabled(false);

	UWorld* World = GetWorld();
	if (World)
	{
		APlayerController* FirstPlayerController = World->GetFirstPlayerController();
		if (FirstPlayerController)
		{
			ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FirstPlayerController->GetPawn());
			if (BlasterCharacter)
			{
				BlasterCharacter->ServerLeaveGame();
			}
			else
			{
				ReturnButton->SetIsEnabled(true);
			}
		}
	}

}

OnPlayerLeftGame这样写

void UReturnToMainMenu::OnPlayerLeftGame()
{
	if (MultiplayerSessionsSubsystem)
	{
		MultiplayerSessionsSubsystem->DestroySession();
	}
}

最后我们梳理一下逻辑,一旦在ReturnToMainMenu按下了绑定的按钮,ReturnButtonClicked()执行,ServerRPC:ServerLeaveGame()调用,然后我们进入到BlasterGameMode,调用BlasterCharacter的Elim()方法,Elim()调用MulticastElim网络多播,设置

bLeftGame = true,在计时器结束后,ElimTimerFinished()根据bLeftGame判断是否离开游戏,然后播放委托OnLeftGame.Broadcast(),执行OnPlayerLeftGame(),然后进入OnDestroySession方法,最后因为我们是客户端,执行GameMode为nullptr方法,返回主菜单PlayerController->ClientReturnToMainMenuWithTextReason(FText());

最后我们绑定一下

请添加图片描述

最后我们把计时器放在MulticastElim下,这样计时功能就也能在client上执行了,就是server调用了Elim,然后elim通过multicast传给所有客户端和服务器

请添加图片描述

回顾一下RPC

请添加图片描述

操作结果

请添加图片描述

请添加图片描述

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值