Consistently loop through players in a room

Options
I'm really struggling to find how I can, in an RPC, loop through every player in a consistent order. Preferable GetPlayerNumber.

Here is what I am trying to do...
[PunRPC]
    public void RPC_SetPlayers() {
      GameObject[] playersArray = GameObject.FindGameObjectsWithTag("Player");
      foreach(GameObject plr in playersArray) {
          plr.GetComponent<PointToPointRace>().playersToPositions = true;
      }
    }

Simple stuff, but, each player that runs this RPC will have a different playersArray order. Or at least that's what seems to be happening here.

How can I say, "Get every player in the room and loop through them as gameobjects".
I can see playerList but that returns a player class that can't access the scripts attached to my player right?
Unless I do some convoluted like PhotonView.Find(player.ID) or something right?

I don't know I just want the most logical solution cause my mobile game is getting bogged down and if I don't stomp this out early it will lag.

Thanks

Comments

  • whats happening here is that every client gets that RPC call and then every client also runs through that foreach loop you have.. and theyre ALL setting them.
    you need to make it so just the master client sets it or they all set it individually through customProperties that the master checks for OnPlayerPropertiesUpdate.

    also, im not sure how you're calling that RPC, but it may be being called multiple times..
    If you must achieve this through an RPC though, a simple way to make sure it's only run once is to add:
    [PunRPC]
        public void RPC_SetPlayers() {
         if(!PhotonNetwork.IsMasterClient) return;
    
          GameObject[] playersArray = GameObject.FindGameObjectsWithTag("Player");
          foreach(GameObject plr in playersArray) {
              plr.GetComponent<PointToPointRace>().playersToPositions = true;
          }
        }
    
  • MomasVII
    Options
    I have actually pre RPC called managed who is calling it which is basically what your if statements says there so it is only being run by one player.
    Here is what I'm trying to do.

    It's a racing game so...
    When a player collects a Race object I want to say "Hey all players, here is the predetermined position you will spawn in for the race, i.e. their poll position. Every player is getting poll poisition 0 and it just stacks all the cars on top of each other.
    So I think when they run playerArray they are returning themselves in position 0 and the other playyer in position 1.
    So player 1's array is like
    [0] Me
    [1] Player 2
    and Player 2 is
    [0] Me
    [1] Player 1
    So i think i need a consistent list of players that each player can read from. Or maybe you have another suggestion?
    Thanks

    public void RPC_SetPlayers() {
          GameObject[] playersArray = GameObject.FindGameObjectsWithTag("Player");
          int x = 0;
          foreach(GameObject plr in playersArray) {
              plr.GetComponent<PointToPointRace>().pollPosition = x++;
              plr.GetComponent<PointToPointRace>().playersToPositions = true;
        
          }
        }
    
  • LeeroiJenkiins
    edited December 2020
    Options
    The difference between checking for master when making the RPC call and within the RPC call is:
    1. Check if is master before RPC:
    - only the master calls for it to execute, but all clients still run and process everything in the RPC

    2. Check if is master in RPC:
    - only the master will actually run this RPC in the call, no other client will

    It sounds like you issue is you're only using #1, and since its a racing game, you probably don't want to use #1 as all clients can pickup this object, and not just the master. But you also only want the call to happen once, and the way to ensure that is #2.

    So remove your check for if(PhotonNetwork.IsMasterClient) before calling the RPC and only have that check within the RPC

    Depending on how many of each of these pick up items are in your game / race. You can also achieve this with customProperties and simply in your gameManager check for OnPlayerPropertiesUpdate. This route has more limitations, but nothing a good algorithm couldn't solve.