首页 > 解决方案 > 统一网络 | ClientRpc 在错误的播放器对象上被调用

问题描述

问题:我的RpcDie方法在错误的游戏对象上被调用。

即:当玩家 A 杀死玩家 B 时,死亡的是玩家 A,而不是玩家 B。

但这只是局部的。所以上述行为只发生在玩家 A 的游戏中,而在玩家 B 的游戏中,一切似乎都按预期发生。反之亦然。

所以:玩家 A 杀死了玩家 B。从玩家 A 的角度来看,他们已经死了,玩家 B 还活着。从玩家 B 的角度来看,他们已经死了,而玩家 A 还活着。


Update我脚本的方法中,我PlayerHealth检查玩家的 hp 是否小于 1。如果是,那么我调用该CmdDie方法:

if (playerHealth < 1)
     CmdDie(); 

CmdDie我调用我的RpcDie方法:

// Calls RpcDie
[Command]
public void CmdDie ()
{
    RpcDie(); 
}

// Removes the player from the game when killed by another player
[ClientRpc]
void RpcDie ()
{
    // Checks
    if (!isLocalPlayer || PlayerUnit.isDead) return;

    // Toggles + updates     
    StopAllCoroutines(); 
    GameObject.Find("MapManager").GetComponent<GameManager>().playerCount--;
    GetComponent<Renderer>().enabled = false;
    PlayerUnit.isDead = true; 

    // Ragdoll
    ragdoll.SetActive(true); 
    foreach (Transform t in ragdoll.transform) 
       t.transform.position = gameObject.transform.position;
}

从调试中我知道玩家的健康正在正确的游戏对象上减去。只有当玩家死亡时,才会发生这种“切换”。

标签: c#unity3dnetworking

解决方案


根据我的假设,playerHealth并不是说玩家实际上是“谁”;无论是它Player A还是Player B。脚本不知道健康应该减少为Player B,而不是Player A

每个玩家都会有一个PlayerID; 因此,Player A会有PlayerID: 1,并且Player B会有PlayerID: 2

更技术性的场景是客户端到服务器的通信。当Player A想要攻击Player B时,客户端(即Player A)会向RPC服务器发送一个他想要攻击的请求Player B

服务器会收到一个“数据包”,其中包含从 发送的信息RPC,包括:PlayerID发起攻击的人(在本例中是PlayerID: 1(A)),以及PlayerID被攻击的人(PlayerID: 2)。数据包中会有更多信息,例如WeaponID,等等。

最后,服务器会向RPC每个人发送另一个伪代码,类似于ReducePlayerHealth(int playerID, int healthAmount, RPC.NotifyAll)

该方法将向游戏中的每个玩家发送一个数据包,客户端将在该数据包中降低该特定玩家的健康状况。服务器必须始终处于指挥状态;因此,服务器设置数据,客户端读取数据。

PS:不得不将其发布为答案,因为我无法在您问题的评论部分输入更多字符。


推荐阅读