PUN - Main Camera not working when more than one player exist

Poyraz
Poyraz
Hello everyone,

I would like to share my problem with PUN and looking for an explanation or solution if possible. I have used official PUN tutorial and extended it with my own prefabs with success. I can join rooms with multiple clients and instantiate my ship prefab.

Basic concept is that there is a gameobject called "CameraPivot" with "MainCamera" as its child object. Whenever, a player joins, the CameraPivot object has to be attached to the instantiated player ship locally. If there is only the host, it works OK. When a client joins, the camera works for the client side as well. However, the CameraPivot object with MainCamera gets reset to intial position for the host and camera gets locked. I connected up to 5 clients to the host, and all the clients work flawless but the host.

[img][/img]J6qtfOC.png

I have found that others have similar issues as in below link as well,
https://forum.unity.com/threads/photon-cameras-not-working-when-more-than-one-exist.691867/

Also, when I created and joined the scene with 6 players, the problem occured to be related only to the host player. I disconnected the host, the second player becomes the host. And right after the second player becomes host, it loses the camarapivot with maincamera. When I disconnected the second player which is the host now, the same happens with the 3rd player.

I tried assigning the camerapivot both from gamemanager and the player prefab. Below is the GameManager script that instantiates the players and relocates cameras and the Camera script. So anyone has any idea why this happens or how to overcome this issue? (I am quite new to both Unity and Photon, so I might have overlooked something easy)

void Start()
{
Instance = this;
if (playerPrefab == null)
{
Debug.LogError("<Color=Red><a>Missing</a></Color> playerPrefab Reference. Please set it up in GameObject 'Game Manager'", this);
}
else if (ShipManager.LocalPlayerInstance == null)
{
Debug.LogFormat("We are Instantiating LocalPlayer from {0}", SceneManagerHelper.ActiveSceneName);
// we're in a room. spawn a character for the local player. it gets synced by using PhotonNetwork.Instantiate
GameObject LocalShip = PhotonNetwork.Instantiate(this.playerPrefab.name, new Vector3(UnityEngine.Random.Range(0, 200), 3, 0f), Quaternion.identity, 0);
if (!LocalShip.GetPhotonView().IsMine)
{
Camera.main.GetComponent<CameraOrbit>().enabled = false;
}
else
{
Camera.main.GetComponent<CameraOrbit>().enabled = true;

CamPivot = GameObject.Find("CameraPivot");

CamPivot.GetComponent<CameraSystem>().shipView = LocalShip.GetComponent<CameraAssign>().sView;
CamPivot.GetComponent<CameraSystem>().portsideView = LocalShip.GetComponent<CameraAssign>().prtView;
CamPivot.GetComponent<CameraSystem>().starboardView = LocalShip.GetComponent<CameraAssign>().stbView;

Camera.main.GetComponent<CameraOrbit>().victory = LocalShip;
}
}
else
{
Debug.LogFormat("Ignoring scene load for {0}", SceneManagerHelper.ActiveSceneName);
}
}

Comments

  • I'd guess that every player instantiates a ship or such. A script on said script will position the camera and so on.
    If so, the master will instantiate a second ship, when the second player joins. All scripts on the prefab run again.
    On instantiated objects/prefabs, check if the scripts runs for the creator's client. You can check photonView.IsMine for that. Only if the object is the local player's object, the scripts should set the camera.
  • Tobias wrote: »
    I'd guess that every player instantiates a ship or such. A script on said script will position the camera and so on.
    If so, the master will instantiate a second ship, when the second player joins. All scripts on the prefab run again.
    On instantiated objects/prefabs, check if the scripts runs for the creator's client. You can check photonView.IsMine for that. Only if the object is the local player's object, the scripts should set the camera.

    Thank you for your response Tobias!

    Indeed initially, the script for attaching camera was on player prefab and I tried the first line below as "if(PhotonViev.IsMine)" to detect if the player is local or not. I had the same problem with that concept, too. So, I tried to use it on GameManager script on local scene, but the result is again same.
    if (!LocalShip.GetPhotonView().IsMine)
    {
    Camera.main.GetComponent<CameraOrbit>().enabled = false;
    }
    else
    {
    Camera.main.GetComponent<CameraOrbit>().enabled = true;

    CamPivot = GameObject.Find("CameraPivot");

    CamPivot.GetComponent<CameraSystem>().shipView = LocalShip.GetComponent<CameraAssign>().sView;
    CamPivot.GetComponent<CameraSystem>().portsideView = LocalShip.GetComponent<CameraAssign>().prtView;
    CamPivot.GetComponent<CameraSystem>().starboardView = LocalShip.GetComponent<CameraAssign>().stbView;

    Camera.main.GetComponent<CameraOrbit>().victory = LocalShip;
    }

    Just a thought experiment, if the client prefabs would cause this issue, then I should have the similar effect when a 3rd player joins. In that case, 1st and 2nd clients should lose camera and only 3rd one should have it. However, the fact is only host loses the camera, whereas 2nd and 3rd clients keep their cameras flawlessly.
  • Tobias wrote: »
    I'd guess that every player instantiates a ship or such. A script on said script will position the camera and so on.
    If so, the master will instantiate a second ship, when the second player joins. All scripts on the prefab run again.
    On instantiated objects/prefabs, check if the scripts runs for the creator's client. You can check photonView.IsMine for that. Only if the object is the local player's object, the scripts should set the camera.

    Thank you for your response Tobias!

    Actually, what you offered was initially what I did with no success. I had the script for allocating the camera attached at player ship prefab with "if(PhotonView.IsMine)" line. The result was same, so I tried it with local GameManager object as in below script locally.
    void Start()
    {
    Instance = this;
    if (playerPrefab == null)
    {
    GameObject 'Game Manager'", this);
    }
    else if (ShipManager.LocalPlayerInstance == null)
    {
    GameObject LocalShip = PhotonNetwork.Instantiate(this.playerPrefab.name, new Vector3(UnityEngine.Random.Range(0, 200), 3, 0f), Quaternion.identity, 0);
    if (!LocalShip.GetPhotonView().IsMine)
    {
    Camera.main.GetComponent<CameraOrbit>().enabled = false;
    }
    else
    {
    Camera.main.GetComponent<CameraOrbit>().enabled = true;

    CamPivot = GameObject.Find("CameraPivot");

    CamPivot.GetComponent<CameraSystem>().shipView = LocalShip.GetComponent<CameraAssign>().sView;
    CamPivot.GetComponent<CameraSystem>().portsideView = LocalShip.GetComponent<CameraAssign>().prtView;
    CamPivot.GetComponent<CameraSystem>().starboardView = LocalShip.GetComponent<CameraAssign>().stbView;

    Camera.main.GetComponent<CameraOrbit>().victory = LocalShip;
    }
    }

    Just a though experiment here: if the script would cause the host losing the camera, when 2nd player connects, then the 2nd player should also lose the camera when the 3rd player joins the room. However, this was not the case. When there is 3 players present, only host loses the camera whereas Player 2 and 3 has working their cameras flawlessly.

    Another experiment I have done is that, I connected 5 clients to a host, with a total number of 6 players. Host lost its camera upon the entry of 2nd player, but the camera for other 5 clients work perfectly. When I disconnect the host, the second player becomes host and then directly loses its camera.
  • Just to update, I have found out the root cause of the problem after going through all scripts in the scene.

    Since I have extended and modified the official photon pun tutorial launcher scene, the host was actually trying to change the scene according to the player count although there is only one scene existing.

    Now it is working for host and all clients without any problem.