Unity Networking 2d 游戏,ClientRpc 无法正常工作
Unity Networking 2d game, ClientRpc not working correctly
我正在为我的学校项目联网一个 2d 游戏,我在尝试在网络场景中制作玩家 "Evolve" 时遇到了问题。播放器只会在客户端正确进化,而不会在主机上正确进化。导致问题的代码在 Evolve 脚本中的某处,但我不知道如何通过代码显示问题,因为问题在于代码的制定。
因此,我附上了代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;
public class Evolve : NetworkBehaviour {
public bool canEvolve;
public bool isEvolving;
public int evoTimer;
public int timeToEvolve;
public int currentEvo;
public GameObject Evo0;
public GameObject Evo1;
public GameObject Evo2;
public GameObject nextEvo;
public GameObject nextA_Atk;
public GameObject nextB_Atk;
// Use this for initialization
void Start() {
canEvolve = true;
isEvolving = false;
evoTimer = 0;
timeToEvolve = GameObject.FindGameObjectWithTag("Settings").GetComponent<GameSettings>().timeToEvolve;
currentEvo = -1;
RpcCallEvolve();
}
// Update is called once per frame
void Update() {
if (!isLocalPlayer)
{
return;
}
if ((Input.GetButton("Evolve")) && (canEvolve == true))
{
isEvolving = true;
evoTimer += 1;
if (evoTimer >= timeToEvolve)
{
RpcCallEvolve();
}
}
else
{
isEvolving = false;
evoTimer = 0;
}
}
[ClientRpc(channel = 0)]
void RpcCallEvolve()
{
currentEvo += 1;
switch (currentEvo)
{
case 0:
nextEvo = Instantiate(Evo0) as GameObject;
break;
case 1:
nextEvo = Instantiate(Evo1) as GameObject;
break;
case 2:
nextEvo = Instantiate(Evo2) as GameObject;
break;
case 3:
Win(name);
break;
}
GetComponent<SpriteRenderer>().sprite = nextEvo.GetComponent<SpriteRenderer>().sprite;
GetComponent<PolygonCollider2D>().points = nextEvo.GetComponent<PolygonCollider2D>().points;
canEvolve = true;
evoTimer = 0;
Destroy(nextEvo);
}
void Win(string player)
{
Debug.Log("Winner is " + player);
gameObject.SetActive(false);
}
}
还有一个 link 下载完整的项目,如果这有助于人们找出问题。 https://1drv.ms/u/s!ArLjF5CAV1VwgbxZdCQkb_9PZ_j5kw
我不需要修复或整理其余代码,只需要有关可能解决上述问题的信息。
非常感谢所有提供帮助的人。
查看您的脚本后,似乎存在一些问题。首先,让我们回顾一下使用 ClientRPC 的一些规则:
- ClientRPC 在 server/host 上调用,相应的方法在所有客户端(包括主机,因为主机是服务器 和一个客户合并)
- ClientRPC 应该只能在服务器上调用,否则它们将无法正常工作。客户端 RPC 可以 由客户端调用,但它们不会向服务器发送任何数据,它会像普通方法一样工作。
现在让我们看看您的脚本。您的 RpcCallEvolve
方法在 Update 方法中被调用,但是您首先要检查的 是脚本是否在本地播放器上。这引入了一些问题,主要是 RpcCallEvolve
方法只会在拥有该播放器的客户端上调用。如果这恰好在 主机的播放器 上被调用,脚本应该可以正常工作,因为 ClientRPC 无论如何都会在服务器上被调用。但是,如果在您的客户端上调用它,它将像常规的本地方法一样工作(如我们前面提到的)。我建议使用命令,以保证在服务器上调用 ClientRPC。命令仅适用于播放器对象,因此请记住此 Evolve
脚本必须在播放器对象上。
[Command]
public void CmdServerEvolve ()
{
RpcCallEvolve();
}
因此,不要在更新函数中调用 RpcCallEvolve
,而是调用 CmdServerEvolve
。如果有任何不清楚的地方,请随时提问。希望这对您有所帮助!
我正在为我的学校项目联网一个 2d 游戏,我在尝试在网络场景中制作玩家 "Evolve" 时遇到了问题。播放器只会在客户端正确进化,而不会在主机上正确进化。导致问题的代码在 Evolve 脚本中的某处,但我不知道如何通过代码显示问题,因为问题在于代码的制定。 因此,我附上了代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;
public class Evolve : NetworkBehaviour {
public bool canEvolve;
public bool isEvolving;
public int evoTimer;
public int timeToEvolve;
public int currentEvo;
public GameObject Evo0;
public GameObject Evo1;
public GameObject Evo2;
public GameObject nextEvo;
public GameObject nextA_Atk;
public GameObject nextB_Atk;
// Use this for initialization
void Start() {
canEvolve = true;
isEvolving = false;
evoTimer = 0;
timeToEvolve = GameObject.FindGameObjectWithTag("Settings").GetComponent<GameSettings>().timeToEvolve;
currentEvo = -1;
RpcCallEvolve();
}
// Update is called once per frame
void Update() {
if (!isLocalPlayer)
{
return;
}
if ((Input.GetButton("Evolve")) && (canEvolve == true))
{
isEvolving = true;
evoTimer += 1;
if (evoTimer >= timeToEvolve)
{
RpcCallEvolve();
}
}
else
{
isEvolving = false;
evoTimer = 0;
}
}
[ClientRpc(channel = 0)]
void RpcCallEvolve()
{
currentEvo += 1;
switch (currentEvo)
{
case 0:
nextEvo = Instantiate(Evo0) as GameObject;
break;
case 1:
nextEvo = Instantiate(Evo1) as GameObject;
break;
case 2:
nextEvo = Instantiate(Evo2) as GameObject;
break;
case 3:
Win(name);
break;
}
GetComponent<SpriteRenderer>().sprite = nextEvo.GetComponent<SpriteRenderer>().sprite;
GetComponent<PolygonCollider2D>().points = nextEvo.GetComponent<PolygonCollider2D>().points;
canEvolve = true;
evoTimer = 0;
Destroy(nextEvo);
}
void Win(string player)
{
Debug.Log("Winner is " + player);
gameObject.SetActive(false);
}
}
还有一个 link 下载完整的项目,如果这有助于人们找出问题。 https://1drv.ms/u/s!ArLjF5CAV1VwgbxZdCQkb_9PZ_j5kw
我不需要修复或整理其余代码,只需要有关可能解决上述问题的信息。
非常感谢所有提供帮助的人。
查看您的脚本后,似乎存在一些问题。首先,让我们回顾一下使用 ClientRPC 的一些规则:
- ClientRPC 在 server/host 上调用,相应的方法在所有客户端(包括主机,因为主机是服务器 和一个客户合并)
- ClientRPC 应该只能在服务器上调用,否则它们将无法正常工作。客户端 RPC 可以 由客户端调用,但它们不会向服务器发送任何数据,它会像普通方法一样工作。
现在让我们看看您的脚本。您的 RpcCallEvolve
方法在 Update 方法中被调用,但是您首先要检查的 是脚本是否在本地播放器上。这引入了一些问题,主要是 RpcCallEvolve
方法只会在拥有该播放器的客户端上调用。如果这恰好在 主机的播放器 上被调用,脚本应该可以正常工作,因为 ClientRPC 无论如何都会在服务器上被调用。但是,如果在您的客户端上调用它,它将像常规的本地方法一样工作(如我们前面提到的)。我建议使用命令,以保证在服务器上调用 ClientRPC。命令仅适用于播放器对象,因此请记住此 Evolve
脚本必须在播放器对象上。
[Command]
public void CmdServerEvolve ()
{
RpcCallEvolve();
}
因此,不要在更新函数中调用 RpcCallEvolve
,而是调用 CmdServerEvolve
。如果有任何不清楚的地方,请随时提问。希望这对您有所帮助!