Instantiated prefabs don't show.

Options
Hi.

I'm pretty new to Photon, but as far as I understood from the documents, instantiated objects should exist already when new players join the room/scene.

In my case, I have a lobby scene where players join one by one after joining the room in the last scene. They instantiate their gameobject at start method (it includes a toggle for showing if player is ready or not). But clients can't see the objects that other players have instantiated via PhotonNetwork.Instantiate. Am I missing something or shouldn't they be automatically there?

Comments

  • Tobias
    Options
    We don't know enough about your project and possible causes, so I can only recommend reading and coding-along the PUN Basics Tutorial. It does change scenes and instantiates bots to control.
    You could use that as reference to figure out where your project skips a step or doesn't handle some messages or such.
  • Fraiyn
    Options
    Alright, let me clarify the code.

    I have a join/create room scene with one InputField for joining the room(and a join button) and a button for creating a room. Then I have an empty gameobject with this script:
    public class LobbyManager : MonoBehaviourPunCallbacks
    {
        [SerializeField]
        InputField JoinRoomInput;
    
        private void Start()
        {
            PhotonNetwork.AutomaticallySyncScene = true;
        }
        public override void OnLeftLobby()
        {
            PhotonNetwork.Disconnect();
            SceneManager.LoadScene("Menu");
        }
    
        public void LeaveLobby()
        {
            Debug.Log("Player left the lobby");
            PhotonNetwork.LeaveLobby();
        }
    
        public void CreateRoom()
        {
            Debug.Log("Player creates a room");
            PhotonNetwork.CreateRoom("test", new RoomOptions { MaxPlayers = 4 });
        }
    
    
        public void JoinRoom()
        {
            Debug.Log("Joining a room named: " + JoinRoomInput.text);
            PhotonNetwork.JoinRoom(JoinRoomInput.text);
        }
    
        public override void OnJoinedRoom()
        {
            Debug.Log("Joined a room successfully");
            PhotonNetwork.LoadLevel("ReadyRoom");
        }
    
    }
    

    And this works fine. But then, in the ReadyRoom scene, I have simple spots to instantiate toggles and a ready button. The code looks like this:
    public class GameManager : MonoBehaviourPunCallbacks, IPunObservable
    {
        // Gameobject that is instantiated from the Resources folder
        [SerializeField] GameObject TogglePrefab;
        // Just positions where to Instantiate prefabs
        [SerializeField] Vector3[] TogglePos;
        Toggle playerToggle;
        PhotonView view;
    
        private void Start()
        {
            // The idea is, that players instantiate their own toggle when they arrive in the scene
            addPlayerToggle(PhotonNetwork.LocalPlayer);
    
            // To get the toggle they're supposed to own
            view = playerToggle.GetComponent<PhotonView>();
        }
    
        public override void OnPlayerEnteredRoom(Player newPlayer)
        {
            Debug.Log("OnPlayerEnteredRoom has been called");
            Debug.Log(newPlayer.NickName +" has joined the room");
        }
    
        // To be able to click readybutton and that makes their toggle mark itself as on
        public void playerIsReady()
        {
            if (view.IsMine)
            {
                Debug.Log(PhotonNetwork.LocalPlayer.NickName + " is toggling ready");
                playerToggle.isOn = !playerToggle.isOn;
            }
        }
    
        public void addPlayerToggle(Player player)
        {
            Debug.Log(player.NickName + " added to the game");
            var p = PhotonNetwork.CurrentRoom.PlayerCount - 1;
            var prefab = PhotonNetwork.Instantiate(TogglePrefab.name, new Vector3(TogglePos[p].x, TogglePos[p].y), Quaternion.identity);
            var canvas = FindObjectOfType<Canvas>();
            prefab.transform.SetParent(canvas.transform, false);
            playerToggle = prefab.GetComponent<Toggle>();
            var textc = playerToggle.GetComponentInChildren<Text>();
            textc.text = player.NickName;
        }
    
        public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
        {
            if (stream.IsWriting)
            {
                stream.SendNext(playerToggle.isOn);
            } else
            {
                playerToggle.isOn = (bool)stream.ReceiveNext();
            }
        }
    }
    

    Problems I have noticed with this:
    - By checking the unity Editor, when second player joins the room, they DO instantiate their toggle, but it's world position is completely off the screen. Localplayer sees their own instantiated Toggle just fine. The second player does not see the first player's Toggle because it's off screen as well.

    - The Toggles that other players have, don't have their Label changed to the name. Toggles that player own have the name changed just fine.

    - Player can toggle their own Toggle.isOn just fine. It works. But they don't see the other player's toggle changing at all, even when they press the ready button. I assume this has something to do with the View?
    - If both players have pressed ready on their own screen and see their own Toggle activated, the next time other player presses ready again to "un-ready", they toggle the other player's toggle too.

    There really should be a larger tutorial about OnPhotonSerializeView or how data is transferred between players besides transform, position and scale.

    I have read the basic pun tutorial through, but can't find the solution from there.