C# Unity Networking 2d游戏,客户端RPC无法正常工作

C# Unity Networking 2d游戏,客户端RPC无法正常工作,c#,unity3d,network-programming,unity-networking,unet,C#,Unity3d,Network Programming,Unity Networking,Unet,我正在为我的学校项目建立一个2d游戏网络,当我试图让玩家在网络场景中“进化”时遇到了一个问题。玩家只能在客户端而不是主机上正确进化。导致问题的代码在Evolve脚本中的某个地方,但我不知道如何通过代码显示问题,因为问题在于代码的执行。 因此,我附上了以下两个代码: using System.Collections; using System.Collections.Generic; using UnityEngine.Networking; using UnityEngine; public

我正在为我的学校项目建立一个2d游戏网络,当我试图让玩家在网络场景中“进化”时遇到了一个问题。玩家只能在客户端而不是主机上正确进化。导致问题的代码在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);
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine。联网;
使用UnityEngine;
公共类进化:网络行为{
公共图书馆;
公共利益是自愿的;
公共定时器;
公共时间参与;
公共交通工具;
公共游戏对象Evo0;
公共游戏对象Evo1;
公共游戏对象Evo2;
公共游戏对象nextEvo;
公共游戏对象nextA_Atk;
公共游戏对象nextB_Atk;
//用于初始化
void Start(){
canEvolve=真;
isEvolving=假;
evoTimer=0;
timeToEvolve=GameObject.FindGameObjectWithTag(“设置”).GetComponent().timeToEvolve;
电流EVO=-1;
RpcCallEvolve();
}
//每帧调用一次更新
无效更新(){
如果(!isLocalPlayer)
{
返回;
}
if((Input.GetButton(“Evolve”)&&(canEvolve==true))
{
isEvolving=真;
evoTimer+=1;
如果(evoTimer>=TIMETOVERVE)
{
RpcCallEvolve();
}
}
其他的
{
isEvolving=假;
evoTimer=0;
}
}
[客户端RPC(通道=0)]
void RpcCallEvolve()
{
电流EVO+=1;
开关(电流EVO)
{
案例0:
nextEvo=实例化(Evo0)为游戏对象;
打破
案例1:
nextEvo=实例化(Evo1)为游戏对象;
打破
案例2:
nextEvo=实例化(Evo2)为游戏对象;
打破
案例3:
温(姓名);
打破
}
GetComponent().sprite=nextEvo.GetComponent().sprite;
GetComponent().points=nextEvo.GetComponent().points;
canEvolve=真;
evoTimer=0;
销毁(nextEvo);
}
无效胜利(弦乐演奏者)
{
Log(“获胜者是”+玩家);
gameObject.SetActive(false);
}
}
以及下载完整项目的链接,如果这有助于人们解决问题的话

我不需要修复或整理其余的代码,只需要了解如何解决上述问题


非常感谢所有帮助您的人。

查看您的脚本后,似乎有一些问题。首先,让我们回顾一下使用ClientRPC的一些规则:

  • 在服务器/主机上调用ClientRPC,并在所有客户端上调用相应的方法(包括主机,因为主机是服务器和客户端的组合)
  • 客户端RPC应该只在服务器上调用,否则它们将无法正常工作。客户端可以调用ClientRPCs,但它们不会向服务器发送任何数据,它的工作方式与普通方法相同
现在让我们看一下您的脚本。Update方法会调用
RpcCallEvolve
方法,但首先要检查脚本是否在本地播放器上。这会带来一些问题,主要是
RpcCallEvolve
方法只能在拥有该播放器的客户端上调用。如果在主机的播放机上调用了该脚本,那么脚本应该可以正常工作,因为无论如何都会在服务器上调用ClientRPC。但是,如果在您的客户机上调用它,它将像常规的本地方法一样工作(正如我们前面提到的)。我建议使用命令,以确保在服务器上调用ClientRPC。命令只对玩家对象起作用,因此请记住,此
Evolve
脚本必须在玩家对象上

[Command]
public void CmdServerEvolve () 
{
    RpcCallEvolve();
}

因此,不要在更新函数中调用
RpcCallEvolve
,而是调用
CmdServerEvolve
。如果有任何不清楚的地方,请随时提问。希望这有帮助

非常感谢你,现在有了更多的意义。我不认为我完全理解ClientRpc以前是如何工作的,这有助于澄清这一点。@EMUR UNET一开始就很混乱,如果您还有任何问题,请随时问我!