跳至主要內容

NT-2.2.2|控制权限

Mr.Si大约 3 分钟u++

前言

经过前面几章的讨论我们对UE的网络复制用法有了些许了解,本章将对网络控制权限方面进行进一步深入。

HasAuthority

bool AActor::HasAuthority() const
{
    return (Role == ROLE_Authority);
}
头像
这个我们已经讨论过了,是用于区分服务器还是客户端的

头像

不知道你有没有注意过一个细节,Target is Actor

头像

对哦!为什么?我好像真没看到过其他UObject能直接判断网络权限的!

头像

网络权限Authority是基于 Actor 的网络复制系统建立的,而不是 UObject 的通用机制。


头像

也就说 UObject 没法网络复制?

头像

并不是,只是普通UObject要进行网络复制需要额外开启 Replication Graph 后续我们会进行单独讨论。

ENetRole

bool AActor::HasAuthority() const
{
    return (Role == ROLE_Authority);
}
//其中的Role 就是这个枚举

/** 在本地/远程网络环境中,演员的网络角色 */
UENUM()
enum ENetRole : int
{
	/** 没有角色。 */
	ROLE_None,
	/** 该演员的本地模拟代理。 */
	ROLE_SimulatedProxy,
	/** 该演员的本地自治代理。 */
	ROLE_AutonomousProxy,
	/** 对该演员的权威控制。 */
	ROLE_Authority,
	ROLE_MAX,
};

头像
这些不是我们之前的章节介绍过了?
头像
认识事物的过程本身就是重复再重复。我们必须得有个前因才能解释后果。例如我想给所有端本地独立生成一个球体碰撞。

IsLocallyControlled

bool APawn::IsLocallyControlled() const
{
	return ( Controller && Controller->IsLocalController() );
}
头像

?直接用HasAuthority不就行了?

头像

你再仔细想想!我们的题目是所有端仅本地生成球体碰撞,而HasAuthority 对于服务器来说,所有非本地玩家其实都是True,我们可以拿一个变量来测试。


netrole003.png
netrole003.png
头像
也就是说在同一端口下众生平等,只能区分是否有权限,并不能确定是不是自己。那么怎么区分呢?
头像

其实我们之前已经讨论过了用IsLocallyControlled 来判断是否本地控制。


服务端在Pawn中判断是不是本地

HasAuthority() && IsLocallyControlled()

客户端在Pawn中判断是不是本地

!HasAuthority() && IsLocallyControlled()
环境HasAuthority()IsLocallyControlled()意义说明
✅ 服务端控制的 Pawntruetrue服务器上本地控制的 Pawn(主控)
🟡 服务端复制的 Pawntruefalse服务器上远程控制的 Pawn(非本地)
✅ 客户端本地 Pawnfalsetrue客户端上本地控制的 Pawn(主控)
❌ 客户端远程 Pawnfalsefalse客户端上同步来的其他玩家 Pawn
bool AController::IsLocalController() const
{
	const ENetMode NetMode = GetNetMode();

	if (NetMode == NM_Standalone)
	{
		// Not networked.
		return true;
	}
	
	if (NetMode == NM_Client && GetLocalRole() == ROLE_AutonomousProxy)
	{
		// Networked client in control.
		return true;
	}

	if (GetRemoteRole() != ROLE_AutonomousProxy && GetLocalRole() == ROLE_Authority)
	{
		// Local authority in control.
		return true;
	}

	return false;
}