【问题标题】:Unity Networking | ClientRpc being called on the wrong player object统一网络 | ClientRpc 在错误的播放器对象上被调用
【发布时间】:2019-12-18 18:58:40
【问题描述】:

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

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

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

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


在我的PlayerHealth 脚本的Update 方法中,我检查玩家的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;
}

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

【问题讨论】:

  • PlayerUnit.isDead 是静态的吗?这可能会影响双方球员吗? AB 之间有什么区别?也许命名在客户端混淆了?
  • @derHugo PlayerUnit.isDead 是静态的,但删除它不会改变任何东西。如果命名在客户端混淆,我不确定它是如何发生的,因为即使我删除了 [Command][ClientRpc] 属性(即使它们成为普通方法,与我完成播放器的方式完全相同运动)没有任何变化。此外,在同时运行客户端和主机时 - 我注意到在玩家 A 的屏幕上,玩家 A 在杀死玩家 B 时死亡。但在玩家 B 的屏幕上却相反。我已将此添加到问题中。

标签: c# unity3d networking


【解决方案1】:

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

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

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

服务器将收到一个“数据包”,其中包含从RPC 发送的信息,包括:发起攻击的PlayerID(在本例中为PlayerID: 1 (A))和另一个@987654339 @谁被攻击了(PlayerID: 2)。数据包中会包含更多信息,例如WeaponID,等等。

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

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

P.S:必须将其发布为答案,因为我无法在您问题的评论部分输入更多字符。

【讨论】:

  • 只是一个旁注,但 afaik 玩家 ID 通常基于 0
  • 您好,感谢您的意见。我如何告诉PlayerHealth 玩家是谁?我了解网络在您所描述的级别上是如何工作的,但我很困惑,因为我的玩家移动方式与我的 PlayerHealth 脚本几乎相同,但效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2016-10-25
相关资源
最近更新 更多