我对何时触发 RPC 感到非常困惑。我现在拥有的是:
玩家 1 是服务器/主机,玩家 2 是客户端。他们都可以击落随机产生的敌方飞机。玩家 1(主机)始终是生成敌人的人,这是通过
PhotonNetwork
: 完成的
if (PhotonNetwork.IsMasterClient)
{
PhotonNetwork.Instantiate(enemyPrefab.name, spawnPosition, Quaternion.identity);
}
当任何玩家射击时,都会从玩家的实例(主机/客户端 - 无论射击者)实例化一颗子弹,这也是通过 PhotonNetwork.Instantiate 完成的:
// Update method in PlayerController.cs
if (Input.GetKey(KeyCode.Space) || Input.GetKey(KeyCode.RightShift))
{
PhotonNetwork.Instantiate(bulletPrefab.name, transform.position, Quaternion.identity);
}
子弹会一直行进,直到击中敌人或变得隐形。当子弹变得不可见时,我只是使用Destroy方法,没有任何网络。
// BulletController.cs
private void OnBecameInvisible()
{
Destroy(gameObject);
}
所以这意味着,每个玩家都在追踪其他玩家的子弹,并摧毁每一颗超出视野的子弹,对吧?我尝试只在 master 上使用
PhotonNetwork.Destroy()
执行此操作,但是当客户端实例化项目符号时,这会引发错误,因为服务器不拥有该项目符号的实例。那么,让每个客户端追踪每颗子弹并销毁它正常吗?请问删除该对象的最佳方法是什么?
同样,我也遇到了移除敌人的问题。敌人可以被任何玩家的子弹杀死,但他们都是从服务器产生的,所以我现在的情况是,当任何子弹击中玩家时,我:
OnTriggerEnter
如果子弹是我的,通过 RPC 销毁它(这没问题 - 所有客户端都会删除子弹)
再次尝试移除敌人
onTriggerEnter
,使用:
if (collision.tag.ToLower() == "player")
{
view.RPC(nameof(RpcDestroyGameObject), RpcTarget.All);
}
但不知何故,每次客户端击中敌人时,敌人都不会被移除。当服务器命中它时,它会立即被删除。如果我尝试在这里使用
PhotonNetwork.Destroy()
,我会收到大量错误,并且我不知道如何测试或调试网络游戏。
所以,我想问题是:当客户端触发 Master 上创建的对象时,如何删除它?
通常 PhotonNetwork.Destroy() 应该可以工作,但如果它没有在项目符号中添加一个名为“Destroyer”或其他名称的简单脚本。其中使用 RPC 来销毁对象(这需要对象上的 PhotonView 组件)
public void DestroyOnNetwork()
{
GetComponent<PhotonView>().RPC("NetworkDestroy", RpcTarget.AllBuffered);
}
[PunRPC]
private void NetworkDestroy()
{
Destroy(this.gameObject);
}
不要忘记使用 Photon.Pun