SpawnPosition, weird behavior

Options
Hallo,
im tryin to Explain.
If 2 Players join a Room, only the MasterClient can Start the Match. MasterClient start the Match and via
PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.room.PlayerCount); Like in the Tutorial the correct Room get Loaded.

Now the GameManager recieve spawnPositions from SpawnPoint.cs wich placed empty GameObjects .

SpawnPoint.cs
public bool playerLocated = false; private void Start() { GameManager.Instance.spawnPosition.Add(this); } public void RPCCall() { photonView.RPC("Located", PhotonTargets.AllBuffered, true); } public Vector3 GetPosition() { return transform.position; } [PunRPC] void Located(bool value) { if (!playerLocated) playerLocated = value; }

then the GameManager start to for (int i = 0; i < spawnPosition.Count; i++) { if (!spawnPosition[i].playerLocated) { CreatePlayer(i); } }
GameObject player = PhotonNetwork.Instantiate(this.playerPrefab.name, spawnPosition[i].GetPosition(), Quaternion.identity, 0);
after this i call
spawnPosition[i].RPCCall();
so it marks the playerLocated bool to true
now the next Instantiated player cant use the same Position, thats what i think.

if the FirstPlayer(MasterClient) is the UnityEditor and the 2nd Player is a Build Instance this works perfect every player get spawned at a unique spawnPoint.
But if the FirstPlayer(MasterClient) is the Build Instance and 2nd Player whatever they both get Spawned at the same Place.
any Help pls?

Comments

  • S_Oliver
    Options
    What can i do else for a unique spawn position?
  • Hi @S_Oliver,

    I'm currently not sure if each client calls the above for-loop from the GameManager, which I think won't work very well at all. So you maybe want to think about the following approach and let the MasterClient decide where each player gets spawned. Therefore only the MasterClient needs a list of all available SpawnPoints and uses the RaiseEvent function, to inform certain clients about their spawn position. When a client receives this special event, he can instantiate his characters by using PhotonNetwork.Instantiate(...);. The necessary OnEvent handler can be placed in the GameManager for example. For more information you can take a look at the RPCs and RaiseEvent documentation page.
  • S_Oliver
    S_Oliver ✭✭✭
    edited October 2017
    Options
    Ok thank you that helps me a lot!
    It works better...but

    Thats my Event.
    void OnEventRaised(byte eventcode, object content,int senderid) { Debug.Log(string.Format("OnEventRaised: {0}, {1}, {2}", eventcode, content, senderid)); if(eventcode == 0) { object[] data = (object[])content; Vector3 position = (Vector3)data[0]; for(int i = 0; i< data.Length;i++) { print(data[i]); } if (!PhotonNetwork.isMasterClient) ClientCreatePlayer(position); } }


    and thast the way i call it

    if(PhotonNetwork.isMasterClient && _countdown == countdown) { MasterClientCreatePlayer(); print(PhotonNetwork.playerList.Length); for (int i = 0; i < PhotonNetwork.playerList.Length; i++) { Vector3 newClientpos = spm.GetNotFlaggedSpawnPoint(); PhotonNetwork.RaiseEvent(0, new object[] { newClientpos }, true, new RaiseEventOptions() { Receivers = ReceiverGroup.All, CachingOption = EventCaching.AddToRoomCache }); } }



    and i reworked my SpawnPointManager.cs
    [SerializeField]Transform[] spawnPoints; [SerializeField]bool[] spawnFlag; int index; private void Start ( ) { if (PhotonNetwork.isMasterClient) { Initialize(); } else return; } void Initialize() { //KnuthShuffleMyArray(spawnPoints); spawnFlag = new bool[spawnPoints.Length]; for (int i = 0; i < spawnFlag.Length; i++) { spawnFlag[i] = true; } } private void KnuthShuffleMyArray (Transform[] array) { //Knuth shuffle algorithm for (int i = 0; i < array.Length; i++) { Transform temp = array[i]; int r = Random.Range(i, array.Length); array[i] = array[r]; array[r] = temp; } } public Vector3 GetSpawnPoint() { for (int i = 0; i < spawnPoints.Length; i++) { if (spawnFlag[i] == true) { index = i; return spawnPoints[index].position; } } Debug.LogError("All SpawnPoints are Flagged."); return Vector3.zero; } public Vector3 GetNotFlaggedSpawnPoint() { for(int i = 0; i< spawnPoints.Length;i++) { if (spawnFlag[i] == true) { index = i; FlagPoint(index,false); return spawnPoints[index].position; } } Debug.LogError("All SpawnPoints are Flagged."); return Vector3.zero; } void FlagPoint(int i,bool value) { spawnFlag[i] = value; }


    so the MasterClient get a uniqe SpawnPosition, but all other Clients spawn in the same Position
    should i a play with CachingOption = EventCaching ?
  • so the MasterClient get a uniqe SpawnPosition, but all other Clients spawn in the same Position should i a play with CachingOption = EventCaching ?


    No, you don't need Caching here I guess and can remove this option.
    The players spawn at the same position, because every client receives this event if I'm not mistaken. You can use the RaiseEventOptions to select specific players who will receive this event: TargetActors is what you are looking for.
    if (PhotonNetwork.isMasterClient)
    {
        foreach (PhotonPlayer p in PhotonNetwork.playerList)
        {
            Vector3 spawnPos = Vector3.zero; // add your implementation here
            PhotonNetwork.RaiseEvent(0, new object[] { spawnPos }, true, new RaiseEventOptions { TargetActors = new int[] { p.ID } });
        }
    }
    In this example the spawn position is only sent to the player currently 'selected' by the foreach loop.
  • S_Oliver
    S_Oliver ✭✭✭
    edited October 2017
    Options
    That looks promising! But I have to go the work now, I will edit this post when I tested it. Thank you very much!!!

    EDIT: it works Perfect! Thannk you @Christian_Simon !!!
  • S_Oliver
    Options
    It worked like a charm! I tried with diffrent thinks like enums, just wao!RaiseEvent !