Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity 5.5.0f3-使用ClientRpc抛出更新对象;找不到Rpc调用的行为…“;_C#_Unity3d_Unity Networking - Fatal编程技术网

C# Unity 5.5.0f3-使用ClientRpc抛出更新对象;找不到Rpc调用的行为…“;

C# Unity 5.5.0f3-使用ClientRpc抛出更新对象;找不到Rpc调用的行为…“;,c#,unity3d,unity-networking,C#,Unity3d,Unity Networking,我正在做一场团队比赛。每个团队都有自己的后代,目标是摧毁其他团队的后代。产卵以3个对象的形式在网络中设置-一个实际产卵(稍后称为物理产卵),仅对服务器可见,一个名为MapManager的对象同时存在于客户端和服务器中,它通过Rpc调用和一个简单的spawn图形(后面称为可视化spawn)充当信使,出现在客户端和服务器的本地播放器上 public class SpawnerServer : NetworkBehaviour { //used to determine whether has

我正在做一场团队比赛。每个团队都有自己的后代,目标是摧毁其他团队的后代。产卵以3个对象的形式在网络中设置-一个实际产卵(稍后称为物理产卵),仅对服务器可见,一个名为MapManager的对象同时存在于客户端和服务器中,它通过Rpc调用和一个简单的spawn图形(后面称为可视化spawn)充当信使,出现在客户端和服务器的本地播放器上

public class SpawnerServer : NetworkBehaviour {
    //used to determine whether has the health changed
    bool isHealthChanged = false;
    //indicates the team of this spawner via enum state
    public Data.teams myTeamEnum;
    ...
    public RectTransform healthBar;

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //Checking whether the bullet wll damage the spawn
        OnChangeHealth(healthPoints);
    }
    //if the health changed, change the healthbar as well
    public void OnChangeHealth(float healthPoints)
    {
        if (isServer)
        {
            ...
            isHealthChanged = true;
        }
    }
     //returns the deltaSize of the healthbar
     public Vector2 GetHealthbarSizeDelta()
    {
        return healthBar.sizeDelta;
    }
    //switches the healthChanged bool back to false. Called by the MapManager
    public void UncheckHealthChanged()
    {
        isHealthChanged = false;
    }
    //returns the state of the healthChanged bool
    public bool IsHealthChanged()
    {
        return isHealthChanged;
    }
}
public class ClientSpawnControl : NetworkBehaviour {
//the references to scripts of the server spawns, required for checking whether has
//the state of any of the spawns changed
public SpawnerServer serverSpawn1;
public SpawnerServer serverSpawn2;
//the references to spawns that belong to the clients
public SpawnerClient clientSpawn1;
public SpawnerClient clientSpawn2;

//acts as a messenger that forces change of spawn healthbars in clients
[ClientRpc]
private void RpcChangeSpawnersHealthClients(int whatTeam, float healthChangeDelta)
{
    if(clientSpawn1 != null)
    {
        if (whatTeam == (int)clientSpawn1.myTeam)
        {
            clientSpawn1.OnChangeHealth(healthChangeDelta);
            return;
        }
    }
    if(clientSpawn2 != null)
    {
        if (whatTeam == (int)clientSpawn2.myTeam)
        {
            clientSpawn2.OnChangeHealth(healthChangeDelta);
            return;
        }
    }
}
// Update is called once per frame
void Update () {
    if (!isServer)
        return;
    if(serverSpawn1.IsHealthChanged())
    {
        serverSpawn1.UncheckHealthChanged();
        RpcChangeSpawnersHealthClients((int)serverSpawn1.myTeamEnum, serverSpawn1.GetHealthbarSizeDelta().x);
    }
    if (serverSpawn2.IsHealthChanged())
    {
        serverSpawn2.UncheckHealthChanged();
        RpcChangeSpawnersHealthClients((int)serverSpawn2.myTeamEnum, serverSpawn2.GetHealthbarSizeDelta().x);
    }

}
每个对象的网络标识设置分别为:

  • 仅限服务器
  • 本地玩家管理局
  • 无-是一种单一行为
物理产卵判断是否对产卵造成任何伤害,如果是-将旗帜isHealthChanged设置为true

public class SpawnerServer : NetworkBehaviour {
    //used to determine whether has the health changed
    bool isHealthChanged = false;
    //indicates the team of this spawner via enum state
    public Data.teams myTeamEnum;
    ...
    public RectTransform healthBar;

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //Checking whether the bullet wll damage the spawn
        OnChangeHealth(healthPoints);
    }
    //if the health changed, change the healthbar as well
    public void OnChangeHealth(float healthPoints)
    {
        if (isServer)
        {
            ...
            isHealthChanged = true;
        }
    }
     //returns the deltaSize of the healthbar
     public Vector2 GetHealthbarSizeDelta()
    {
        return healthBar.sizeDelta;
    }
    //switches the healthChanged bool back to false. Called by the MapManager
    public void UncheckHealthChanged()
    {
        isHealthChanged = false;
    }
    //returns the state of the healthChanged bool
    public bool IsHealthChanged()
    {
        return isHealthChanged;
    }
}
public class ClientSpawnControl : NetworkBehaviour {
//the references to scripts of the server spawns, required for checking whether has
//the state of any of the spawns changed
public SpawnerServer serverSpawn1;
public SpawnerServer serverSpawn2;
//the references to spawns that belong to the clients
public SpawnerClient clientSpawn1;
public SpawnerClient clientSpawn2;

//acts as a messenger that forces change of spawn healthbars in clients
[ClientRpc]
private void RpcChangeSpawnersHealthClients(int whatTeam, float healthChangeDelta)
{
    if(clientSpawn1 != null)
    {
        if (whatTeam == (int)clientSpawn1.myTeam)
        {
            clientSpawn1.OnChangeHealth(healthChangeDelta);
            return;
        }
    }
    if(clientSpawn2 != null)
    {
        if (whatTeam == (int)clientSpawn2.myTeam)
        {
            clientSpawn2.OnChangeHealth(healthChangeDelta);
            return;
        }
    }
}
// Update is called once per frame
void Update () {
    if (!isServer)
        return;
    if(serverSpawn1.IsHealthChanged())
    {
        serverSpawn1.UncheckHealthChanged();
        RpcChangeSpawnersHealthClients((int)serverSpawn1.myTeamEnum, serverSpawn1.GetHealthbarSizeDelta().x);
    }
    if (serverSpawn2.IsHealthChanged())
    {
        serverSpawn2.UncheckHealthChanged();
        RpcChangeSpawnersHealthClients((int)serverSpawn2.myTeamEnum, serverSpawn2.GetHealthbarSizeDelta().x);
    }

}
MapManager检查物理生成中的标志状态(仅在服务器上检查)以及检测到真值时的标志状态:

  • 将标志重置为
  • 获取healthbar的宽度
  • 将有关healthbar的新宽度和繁殖数量的信息传递给RPC调用rpcchangeprownershealthclients(),该调用函数负责更新可视化繁殖的healthbar的转换数据

    public class SpawnerServer : NetworkBehaviour {
        //used to determine whether has the health changed
        bool isHealthChanged = false;
        //indicates the team of this spawner via enum state
        public Data.teams myTeamEnum;
        ...
        public RectTransform healthBar;
    
        private void OnTriggerEnter2D(Collider2D collision)
        {
            //Checking whether the bullet wll damage the spawn
            OnChangeHealth(healthPoints);
        }
        //if the health changed, change the healthbar as well
        public void OnChangeHealth(float healthPoints)
        {
            if (isServer)
            {
                ...
                isHealthChanged = true;
            }
        }
         //returns the deltaSize of the healthbar
         public Vector2 GetHealthbarSizeDelta()
        {
            return healthBar.sizeDelta;
        }
        //switches the healthChanged bool back to false. Called by the MapManager
        public void UncheckHealthChanged()
        {
            isHealthChanged = false;
        }
        //returns the state of the healthChanged bool
        public bool IsHealthChanged()
        {
            return isHealthChanged;
        }
    }
    
    public class ClientSpawnControl : NetworkBehaviour {
    //the references to scripts of the server spawns, required for checking whether has
    //the state of any of the spawns changed
    public SpawnerServer serverSpawn1;
    public SpawnerServer serverSpawn2;
    //the references to spawns that belong to the clients
    public SpawnerClient clientSpawn1;
    public SpawnerClient clientSpawn2;
    
    //acts as a messenger that forces change of spawn healthbars in clients
    [ClientRpc]
    private void RpcChangeSpawnersHealthClients(int whatTeam, float healthChangeDelta)
    {
        if(clientSpawn1 != null)
        {
            if (whatTeam == (int)clientSpawn1.myTeam)
            {
                clientSpawn1.OnChangeHealth(healthChangeDelta);
                return;
            }
        }
        if(clientSpawn2 != null)
        {
            if (whatTeam == (int)clientSpawn2.myTeam)
            {
                clientSpawn2.OnChangeHealth(healthChangeDelta);
                return;
            }
        }
    }
    // Update is called once per frame
    void Update () {
        if (!isServer)
            return;
        if(serverSpawn1.IsHealthChanged())
        {
            serverSpawn1.UncheckHealthChanged();
            RpcChangeSpawnersHealthClients((int)serverSpawn1.myTeamEnum, serverSpawn1.GetHealthbarSizeDelta().x);
        }
        if (serverSpawn2.IsHealthChanged())
        {
            serverSpawn2.UncheckHealthChanged();
            RpcChangeSpawnersHealthClients((int)serverSpawn2.myTeamEnum, serverSpawn2.GetHealthbarSizeDelta().x);
        }
    
    }
    
这就是引发异常的地方:“在TeamSelector(UnityEngine.GameObject)上未找到传入[ClientRpc:InvokerPCChangesSpawnerHealthClient]的行为,服务器和客户端应具有相同的NetworkBehavior Instances…”

这个错误非常有趣,因为提到的TeamSelector实际上与产卵器更新无关。它在比赛中使用,用来初始化球员的球队数据,仅此而已。甚至更多-其中一个物理派生也以某种方式在客户机上派生,不过如果我没有记错的话,仅限服务器选项应该可以防止此类行为,而且我不会尝试通过网络创建对象

早些时候,我尝试生成使用网络行为网络身份武装的可视化生成——错误是这些对象无法在客户端生成,即使我在网络管理器中注册了对象,甚至使用了该方法 ClientScene.RegisterPrefab()。使得每一种可能的结合,两种情况都没有改变。后来,我将可视化生成重新排列为其当前形式,并尝试在检测到运行状况发生变化时,立即从物理生成中的映射管理器中调用RPC调用。在客户端引发了与上面引用的异常类似的异常,但在TeamSelector对象的位置上使用了一个物理派生的名称。搜索解决方案并没有找到任何可行的方法,例如,我没有任何名称重复但属于不同名称空间的方法

我甚至不知道从哪里寻找问题的根源。在与Unity争论了3天之后,我觉得它只是不想让我创造那个游戏。有人知道是什么导致了这个问题吗

我非常抱歉这篇文章太长,但我不知道如何用更简短的方式来描述这个问题