Search Unity

How to send and receive a seed

Discussion in 'Multiplayer' started by RiokuTheSlayer, Dec 19, 2014.

  1. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Hey all, I have a few questions.

    I'm using Photon with one of my new games, and I have NO idea how to do something. That something is sending and receiving a seed for Random.seed that's specified when the Master Client creates the room.

    I've tried sending the seed every time the player updates, but the "Prop Generator" runs it's script before the player can get the seed. And if I try and use OnPhotonSerializeView to update it, it doesn't work because the for loops to create the objects are located in OnJoinedRoom. I don't know how I'd sort this out so that it works correctly.

    If you guys need any scripts, just ask, but If you can give me a method I can stick into the Prop Generator or something that works, I'd prefer that.

    I'm pretty new to Networking, so I'd appreciate any help.
     
  2. BFGames

    BFGames

    Joined:
    Oct 2, 2012
    Posts:
    1,543
    You could just create a single seed as soon as the game is created and then use that seed on all clients for rest of the game.

    If you do so the important thing is to only create a new random instance ONCE using that seed, and then use random next based on that instance of random. Important part is then to keep track of when people are calling next so some players are not 'ahead' of others.

    If that won't work for you, you need to create a call back method. So when a client who is not the master-client needs a new random number you will ask the master client for a seed and then he will return one (a seed) to a method that will then handle whatever it is you need to handle. This of cause creates a small delay because the message needs to go back and forth.
     
  3. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Yea, I know about all that haha. I just don't know how to actually iterate it in code.

    Well, actually, I do. I just need to figure out a way to ask the master client for the seed the moment they join
     
  4. BFGames

    BFGames

    Joined:
    Oct 2, 2012
    Posts:
    1,543
    There is a OnPlayerJoinRoom method. In the method just check if(PhotonNetwork.isMasterClient), if you are then send the seed to the player who joined using an RPC.

    Or if you want the player to ask just send a RPC with photontarget set to masterclient and then let the masterclient send it back to that certain player (send his view id with the request)
     
  5. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    I don't know how RPCs work honestly, could you link me to a page that explains how to use them?
     
  6. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Okay, correction. I don't know how to send the seed and/or receive it as the player. I don't know how to use RPCs correctly, that's why I made the thread in the first place. I know what I need to do, I just don't know how
     
  7. BFGames

    BFGames

    Joined:
    Oct 2, 2012
    Posts:
    1,543
    Code (csharp):
    1.  
    2.  
    3. void OnPhotonPlayerConnected(PhotonPlayer player)
    4. {
    5.         if (PhotonNetwork.isMasterClient)
    6.         {
    7.             photonView.RPC("SetSeed", player, Seed);
    8.         }
    9. }
    10.  
    11. [RPC]
    12. void SetSeed(int seed)
    13. {
    14.     Seed = seed;
    15. }
    16.  
    17.  
    Something like that....
     
    Enzo1 likes this.
  8. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Trying it now...
     
  9. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    It doesn't look like the second player is getting the seed at all.
     
  10. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Here's my NetworkManager script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class NetworkManager : MonoBehaviour {
    5.  
    6.     public float menuNumber;
    7.     public bool isConnected;
    8.     public string Version;
    9.     public GameObject propGen;
    10.     PhotonView myView;
    11.     public int Seed;
    12.  
    13.     public GameObject playerManager;
    14.  
    15.     // Use this for initialization
    16.     void Start () {
    17.         Seed=(int)Random.Range(0,1000);
    18.         menuNumber=0;
    19.         isConnected=false;
    20.         myView=gameObject.GetComponent<PhotonView>();
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update () {
    25.         if(menuNumber==0){
    26.             return;
    27.         }
    28.         if(menuNumber==1 && !isConnected){
    29.             isConnected=true;
    30.             PhotonNetwork.offlineMode=true;
    31.             ConnectSP();
    32.         }
    33.         if(menuNumber==2 && !isConnected){
    34.             isConnected=true;
    35.             Connect();
    36.         }
    37.     }
    38.  
    39.     void Connect(){
    40.         PhotonNetwork.ConnectUsingSettings(Version);
    41.     }
    42.     void ConnectSP(){
    43.         PhotonNetwork.CreateRoom("");
    44.     }
    45.  
    46.     void OnJoinedLobby(){
    47.         PhotonNetwork.JoinRandomRoom();
    48.         Debug.Log ("OnJoinedLobby");
    49.     }
    50.  
    51.     void OnPhotonRandomJoinFailed(){
    52.         Debug.Log ("OnPhotonRandomJoinFailed");
    53.         PhotonNetwork.CreateRoom("1");
    54.     }
    55.  
    56.     void OnJoinedRoom(){
    57.         Debug.Log ("OnJoinedRoom");
    58.         propGen.GetComponent<PropGen>().GenerateForest(Random.seed);
    59.         SpawnMyPlayer();
    60.     }
    61.  
    62.     void SpawnMyPlayer(){
    63.         GameObject myPlayer = (GameObject)PhotonNetwork.Instantiate("MainPlayer",Vector3.zero+Vector3.up*2,Quaternion.identity,0);
    64.         playerManager.gameObject.SetActive(true);
    65.         myPlayer.GetComponent<NavMeshAgent>().enabled=true;
    66.         myPlayer.GetComponent<CharMoveScript>().enabled=true;
    67.     }
    68.  
    69.     public void setMode(float Mode){
    70.         Debug.Log("Hi!");
    71.         menuNumber=Mode;
    72.     }
    73.  
    74.     void OnPhotonPlayerConnected(PhotonPlayer player)
    75.     {
    76.         if (PhotonNetwork.isMasterClient)
    77.         {
    78.             myView.RPC("SetSeed", player, Seed);
    79.         }
    80.     }
    81.  
    82.     [RPC]
    83.     void SetSeed(int seed)
    84.     {
    85.         Random.seed = seed;
    86.     }
    87. }
    88.  
    Messy, I know. The MenuNumber is changed by a few 4.6 UI buttons I have. All the values are defined in-editor, nothing is empty.
     
  11. BFGames

    BFGames

    Joined:
    Oct 2, 2012
    Posts:
    1,543
    Shouldn't you be using Photon.Monobehaviour?
     
  12. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    .... Honestly, yes. Will that fix it?
     
  13. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    'kay, just threw a bunch of debug.log()'s into my code to make sure that everything is getting the same seed, and it seems like it all is. That means there's something up with my Prop Generation method, but it's weird because it's all based on random numbers, and setting the seed should make all those numbers the same every time, right?

    Here's the generation code:


    Code (CSharp):
    1.     public void GenerateForest(int seed){
    2.  
    3.         Debug.Log("Generating Trees with seed " + Random.seed);
    4.  
    5.             //Forest Generation
    6.         for(int i=0; i<forestNumber; i++){
    7.             Vector3 forestCenter = new Vector3(Random.Range(-WorldRange,WorldRange),0,Random.Range(-WorldRange,WorldRange));
    8.             Instantiate(Crystal,forestCenter,Crystal.transform.rotation);
    9.             for(int i2=0; i2<treeNumber; i2++){
    10.                 foreach(GameObject tree in Trees){
    11.                     Vector3 treePos = new Vector3(Random.Range(-ForestRange,ForestRange),0,Random.Range(-ForestRange,ForestRange));
    12.                     GameObject treeTemp = (GameObject)Instantiate(tree,forestCenter+treePos,Quaternion.Euler(tree.transform.rotation.eulerAngles.x,tree.transform.rotation.eulerAngles.y,tree.transform.rotation.x+Random.Range(-360,360)));
    13.                     treeTemp.transform.parent=gameObject.transform;
    14.                 }
    15.             }
    16.         }
    17.     }
    Wow, that looks so messy on here. I really should clean that up I guess

    Anyway, any ideas?

    Also, I'll be gone the next few days for the holidays, so any replies will be delayed.
     
  14. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Wait a second... I just tested setting the seed to 12345 before generating the forest, and it generates the same one every time. What the heck...
     
  15. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Got it.
     
    Enzo1 likes this.
  16. Enzo1

    Enzo1

    Joined:
    Jun 3, 2015
    Posts:
    2

    helped a lot thanks!