Photon RPC 发送错误的 int 值

Posted

技术标签:

【中文标题】Photon RPC 发送错误的 int 值【英文标题】:Photon RPC sends wrong int values 【发布时间】:2021-08-18 06:55:38 【问题描述】:

所以我尝试使用 RPC 并发送一个 int 列表和一个 int 作为参数,但是,虽然函数正确发送了 int 列表,但它发送的 int 值是错误的,并且对于每个客户端来说都是不同的,即使我正在发送对所有人都具有相同的价值。

这是RPC方法;

[PunRPC]
void GetPlayerCards(int[] _cardListInt, int _gCard)

    if(intPlayerCardlist.Count == 0)
    
        intPlayerCardlist.AddRange(_cardListInt);
    

    foreach (int cardInt in intPlayerCardlist)
    
        if(MyCardlist.Contains(gameFullCardlist.cardList[cardInt])) continue;

        else MyCardlist.Add(gameFullCardlist.cardList[cardInt]);
    

    groundCard = gameFullCardlist.cardList[_gCard];

    Debug.Log("value: " + _gCard + " card name: " + groundCard);

这是从属于主客户端的房间实例化对象中调用的调用方法:

int[] List1 = cardList1.ToArray();
int[] List2 = cardList2.ToArray();
int[] List3 = cardList3.ToArray();
int[] List4 = cardList4.ToArray();
int[] List5 = cardList5.ToArray();
int gCard = cardList5[0];

PhotonView PV_P1 = gamePlayersList[0].GetComponent<PhotonView>();
PhotonView PV_P2 = gamePlayersList[1].GetComponent<PhotonView>();
PhotonView PV_P3 = gamePlayersList[2].GetComponent<PhotonView>();
PhotonView PV_P4 = gamePlayersList[3].GetComponent<PhotonView>();

PV_P1.RPC("GetPlayerCards", PV_P1.Owner, List1, gCard);
PV_P2.RPC("GetPlayerCards", PV_P2.Owner, List2, gCard);
PV_P3.RPC("GetPlayerCards", PV_P3.Owner, List3, gCard);
PV_P4.RPC("GetPlayerCards", PV_P4.Owner, List4, gCard);

如果您发现我为所有客户端发送相同的值但我得到不同的结果,请参阅下面的日志:

游戏管理器和玩家正在使用以下脚本从每个客户端场景中的空游戏对象实例化;

private void Awake() 
        
            //Order of Instantiation is important
            PhotonNetwork.InstantiateRoomObject(InstantiatedPlayersListGameobject.name, Vector3.zero, Quaternion.identity);
            PhotonNetwork.InstantiateRoomObject(cardsDeck.name, Vector3.zero, Quaternion.identity);
            PhotonNetwork.InstantiateRoomObject(GameplayManager.name, Vector3.zero, Quaternion.identity);
        

        void Start() 
        

            if(PhotonNetwork.IsConnectedAndReady)
            
                if (playerPrefab != null)
                
                    GameObject playerInstantiation = PhotonNetwork.Instantiate(playerPrefab.name, Vector3.zero, Quaternion.identity);
                    playerInstantiation.transform.SetParent(InstanceParent.transform, false);
                    playerInstantiation.transform.localScale = Vector3.one;
                    playerInstantiation.transform.localPosition = Vector3.zero;
                    // playerInstantiation.name = (playerInstantiation.GetComponent<PhotonView>().Owner.NickName + " - AN: " + 
                    // playerInstantiation.GetComponent<PhotonView>().Owner.ActorNumber);
                    Debug.Log("player instantiated");
                
                else
                
                    Debug.Log("Place player Prefab");
                         
                
        
    

【问题讨论】:

嗯,从您的日志看来,它被调用了 4 次,每个都有不同的值 => RPC 在哪里/如何准确调用?在我看来,您的四个玩家中的每一个都将它发送给每个其他玩家......您可能只想这样做一次?例如。仅当您是 MasterClient 时? @derHugo 从房间实例化对象调用 RPC,我调用 RPC 4 次,每个玩家一次,这就是它在调试日志中出现 4 次的原因 【参考方案1】:

如果没有更多代码 sn-ps 的详细信息和上下文,很难判断。

不过,我想我知道这里出了什么问题。

您期望:您正在向 四个不同的玩家发送 四个 RPC。

会发生什么:您正在向四个不同的玩家发送 四个 RPC 但是您完成了整个事情 四个 次 => 每个玩家收到的不是一个(如预期的那样)而是四个具有不同值的 RPC。

如果它按预期工作,您将只会看到一个登录您的每个播放器,因为每个播放器应该只收到一个 RPC 调用。相反,您的调用方法似乎在您的四名玩家中的每一个上执行,并且在将这些单独的值发送给其他人之前,每个人都会对卡片进行单独的随机化。


就像在现实生活中你通常有一个“经销商”一样,Photon 提供了这样一个人:所谓的MasterClient

你用来调用这个随机化和 RPC 给每个人的方法应该检查PhotonNetwork.isMasterClient

if(PhotonNetwork.isMasterClient)

    // ...

    int[] List1 = cardList1.ToArray();
    int[] List2 = cardList2.ToArray();
    int[] List3 = cardList3.ToArray();
    int[] List4 = cardList4.ToArray();
    int[] List5 = cardList5.ToArray();
    int gCard = cardList5[0];

    // HINT: In general rather pre-cache and re-use these references
    PhotonView PV_P1 = gamePlayersList[0].GetComponent<PhotonView>();
    PhotonView PV_P2 = gamePlayersList[1].GetComponent<PhotonView>();
    PhotonView PV_P3 = gamePlayersList[2].GetComponent<PhotonView>();
    PhotonView PV_P4 = gamePlayersList[3].GetComponent<PhotonView>();

    PV_P1.RPC("GetPlayerCards", PV_P1.Owner, List1, gCard);
    PV_P2.RPC("GetPlayerCards", PV_P2.Owner, List2, gCard);
    PV_P3.RPC("GetPlayerCards", PV_P3.Owner, List3, gCard);
    PV_P4.RPC("GetPlayerCards", PV_P4.Owner, List4, gCard);

【讨论】:

我认为不需要使用 if(Masterclient),因为 RPC 调用方法是从属于主客户端的单个房间实例化对象调用的: @EustasSilver 再次.. 我目前的印象是,这已经完成了四次,似乎每个现有玩家都完成了一次。 => 总共 16 个 RPC - 4 个玩家各 4 个。我没有任何关于调用此方法的位置的信息,或者是否真的只有一个对象在执行此操作……如果您认为它们相关,请提供更多详细信息;) 首先感谢您的努力。为了更清楚地说明,布局如下;房间实例化一个游戏管理器,将游戏卡分配到 4 个列表中(每个玩家 1 个),游戏将实例化 4 个游戏对象(使用具有 RPC 方法的脚本,然后游戏管理器在每个列表上调用 RPC 函数获得光子视图后的玩家。问题是每个 p 层都获得不同的值,即使我发送相同的变量而不更改它。我希望我设法澄清事情。 game manager 何时以及如何具体实例化? The room instantiates -> 不,某个玩家必须这样做 每个客户端游戏场景在一个已经存在的空对象上都有一个玩家管理器脚本,该脚本使用PhotonNetwork.InstantiateRoomObject(GameManager),这个只实例化一个自动属于该游戏管理器的实例主客户端

以上是关于Photon RPC 发送错误的 int 值的主要内容,如果未能解决你的问题,请参考以下文章

在 Photon Bolt 中,如何将 int 数据列表与事件一起发送到令牌中?

如何使用 Photon 发送结构

有没有办法使用 Photon Pun2 或 Photon Chat 发送或接收图像、音频和视频?

在 Photon Cloud 上使用 Hashtable 发送数据

尝试发送 rpc 请求时发生错误

photon Unity RPC 调用流程