Unity Server GameObject销毁

时间:2018-10-09 10:20:45

标签: unity3d server

我有一个用Unity制作的2D游戏,我希望角色能够发射子弹,并且当子弹击中玩家时将其推回以摧毁子弹。由于服务器无法完美同步,在某些情况下,项目符号会在本地销毁,但不是在所有客户端上销毁,因此我想将其作为[Command]销毁服务器和所有客户端上的销钉。

本地代码如下:

void OnTriggerEnter2D(Collider2D col)
{
    if (col.gameObject.tag == "bullet") 
    {
        Explode (Mathf.Sign (col.attachedRigidbody.velocity.x));
        Destroy(col.gameObject);
    }
}

我试图像这样的多人游戏

[Command]
void CmdOnTriggerEnter2D(Collider2D col)
{
    if (col.gameObject.tag == "bullet") 
    {
        Explode (Mathf.Sign (col.attachedRigidbody.velocity.x));
        Network.Destroy(col.gameObject);
    }
}

但这不起作用..它告诉我

  

CmdOnTriggerEnter2D参数[col]的类型为[Collider2D],它是一个组件。您不能将组件传递给远程呼叫。尝试从组件内部传递数据。

我知道我应该使用另一个参数,但是如何..?如何使此功能在我的服务器上工作?

1 个答案:

答案 0 :(得分:0)

正如您的输出所示,由于网络不知道此引用在其他实例上的位置,因此无法将Collider组件引用作为参数传递。

Unity Documentation for Command中,您可以找到允许哪些值作为参数:

  

允许的参数类型为;

     
      
  • 基本类型(字节,整数,浮点数,字符串,UInt64等)
  •   
  • 内置Unity数学类型(Vector3,四元数等),
  •   
  • 基本类型的数组
  •   
  • 包含允许类型的结构
  •   
  • NetworkIdentity
  •   
  • NetworkInstanceId
  •   
  • NetworkHash128
  •   
  • 带有NetworkIdentity组件的GameObject。
  •   

=>特别注意列表中最底端的元素:

只要col.gameObject上带有NetworkIdentity组件,您就可以简单地传递它!


在强调网络带宽之前,我要检查标记是否已经匹配。含义:请在选项卡上检查本地,并仅使用有效的GameObject参考调用Command。

因此,您的代码应该看起来像

//local
void OnTriggerEnter2D(Collider col)
{
    if (col.gameObject.tag != "bullet") return;

     CmdOnTriggerEnter2D(col.gameObject);
} 

// This is executed only on the server
[Command]
void CmdOnTriggerEnter2D(GameObject col)
{
    // Depending on what Explode does you might want to pass it pack to all clients as well
    // Since currently this will only happen on the server itself!
    Explode (Mathf.Sign (col.attachedRigidbody.velocity.x));
    Network.Destroy(col);  
}

如前所述,您的项目符号对象具有一个NetworkIdentity组件,但我认为,如果我猜这是Network衍生的预制件,那么情况已经如此。


注意

正如我在评论中提到的,我也猜想Explode应该在所有客户端上发生,而不是仅在服务器上发生。在这种情况下,您可以执行以下操作

//local
void OnTriggerEnter2D(Collider col)
{
    if (col.gameObject.tag != "bullet") return;

    // Already get the value needed for the Explode method
    var value= Mathf.Sign (col.attachedRigidbody.velocity.x)

    // Also pass the value so we can provide it to all clients later      
    CmdOnTriggerEnter2D(col.gameObject, value);
} 

// This is executed only on the server
[Command]
void CmdOnTriggerEnter2D(GameObject col, float value)
{
    // Tell all clients to Explode using the passed value
    RpcExplode(value);
    Network.Destroy(col);  
}

// This is called by the server but executed by ALL clients
[ClientRpc]
void RpcExplode(float value)
{
    Explode (value);
}

由于我不知道爆炸所需要的工作:如果需要执行Explode;),请务必销毁子弹对象。