我有一个用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],它是一个组件。您不能将组件传递给远程呼叫。尝试从组件内部传递数据。
我知道我应该使用另一个参数,但是如何..?如何使此功能在我的服务器上工作?
答案 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
;),请务必销毁子弹对象。