Problems to instantiate an object just once

Hi,
I am quite new to Photon and I encountered a problem when I only want an instance to be created once. I have this scenario:
- Players that connect to a room and play together.
- A map that divides in segments and that generates them in a random order for each game.

The thing is that I try to instantiate the map once using Tags, but it seems that every player creates its own map. Here is the code that has every player once they join a room:

[code2=csharp]void OnJoinedRoom ()
{
Vector3 aux = new Vector3 (-9.7f, 0.7f, 0.0f);
if (map == null) {
GameObject mapObj = GameObject.FindWithTag ("map");
if (mapObj == null) { //If the map hasn't been created yet, we do

mapObj = PhotonNetwork.Instantiate("MapManager", Vector3.zero, Quaternion.identity, 0);
}
map = (controlMap)mapObj.GetComponent ("controlMap");
}
//add the first two segments types
actSeg = Instantiate (GetNextFragment(0), new Vector3 (0, 0, 0), Quaternion.identity);
nextSeg = Instantiate (GetNextFragment(1), new Vector3 (20, 0, 0), Quaternion.identity);
}[/code2]

Am I forgetting something? Is there another way to do this?

Comments

  • Unfortunately the OnJoinedRoom callback is done before all of the Instantiate-requests are done.
    That explains why you can't access a dynamically, player-instantiated GO in OnJoinedRoom.

    You can either use a GO in the scene, to sync values to everyone or implement OnPhotonInstantiate() and in that, check if the map is already there.

    You can also check for PhotonNetwork.isMasterClient. If so and the map is not existing, then you should create it. Otherwise, the MasterClient should do this anytime soon (maybe just did).
  • Hi tobias and thank you for your answer.
    I used the isMasterClient variable to create the map once a player has been created. The map creates successfully, but when a client tries to look after a map I am not certain what exactly happens:
    I added GUI labels to keep track of what is going on. The client never creates a map, instead, it looks after one using tags. The label says that the client has found a map successfully, although, that map doesn't equal to that of the master.
    I do not understand what is happening nor what my big mistake is. I made sure that the map was only created by the master.
    Here's some code:
    this function is on the gameManager, it's an object that all clients (and master) have and manages the game info, it is also the one who connects to the Photon network. StartGame initiates the map and is called by players.
    [code2=csharp]public void StartGame(bool createMap)
    {
    Debug.Log ("GM: starting game for a player");
    if (map == null) {
    GameObject mapObj = null;
    if (createMap){
    Debug.Log (">>GM:StartGame: Master connected");
    text = "I am MASTER";
    mapObj = PhotonNetwork.Instantiate ("MapManager", Vector3.zero, Quaternion.identity, 0);
    }
    else{
    Debug.Log (">>GM:StartGame: Client connected");
    text = "I am client";
    mapObj = GameObject.FindWithTag ("map");
    }
    if (mapObj == null){
    Debug.Log (">>GM:StartGame: client didn't find a map");
    text += ". Map is null!!";
    }
    else{
    map = (controlMap)mapObj.GetComponent ("controlMap");
    if(!createMap){
    text+=". Map found!";
    Debug.Log (">>GM:StartGame: client found a map");
    }
    }


    }[/code2]

    StartGame is called by players. I tried to make the call inside the players' code using two functions:
    OnPhotonInstantiate() and at the end of Start()
    Both cases ended up with similar results. Inside those two methods, I just made a call to the player's StartGame function that looks like this:
    [code2=csharp]void StartGame()
    {
    GameObject gm = GameObject.FindWithTag ("GM");
    gameManager gmScript = (gameManager)gm.GetComponent ("gameManager");
    gmScript.StartGame (PhotonNetwork.isMasterClient);
    }[/code2]

    Which simply calls to gameMaster's StartGame function.

    Any ideas of what is my mistake?
  • After giving it more thought, I think that the problem is not in the creation or search of a map. I think that only one map is ever created and that clients are able to get the map correctly. It is like the initialisation of the map runs each time per client. So at the end I have each client with a different map.
    The thing is that maps work with segments. The map has a function to set itself up that generates 100 segments randomly stored in a list. To avoid that each client's map instance has a different list I made this function RPC and only the master client calls it. Still it seems that it is not working. May it be because clients that are not connected yet lose this RPC and the map keeps its list empty? If so, what can be done to solve this?
  • Which RPC? You never mentioned any RPC. If it's buffered, players who join late won't miss it.

    Actually, to make this really lean and nice, you should think about using a "Seed" for your random maps. If the seed for Random is the same on all systems, the sequence of values you get from it is deterministic. So you can generate the map in a deterministic way, too and only have to exchange the seed value. It should be put into a room property via PhotonNetwork.room.SetCustomProperty().
  • Oh, I did not know about these properties. The solution was so simple! I added the seed to the room properties and now it seems to be working just fine. Thanks for your answers Tobias!
  • I'm glad I could help.
    I wasn't aware you already use a seed. Cool you do!
    Let us know if you post some WIP stuff about your game anywhere.