Photon Transform View not syncing players position on both screen

Hi,

I’ve been following the “Get Started” tutorial on the official Photon PUN website, and tried to implement multiplayer on the go on a small project that I had.
Tutorial : Pun 2 0 - Introduction | Photon Engine

I followed everything smoothly until the part where the players position need to be synced accross all
session with a Photon Transform View component. My problem is that the clients are not updating the other player position.

Here is a video of what I mean :

Here is a screen capture of my player prefab :

Here is my Launch script (it creates a room for the player and change the scene when there are two players in the same room) :

using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class Launch : MonoBehaviourPunCallbacks
{
    [Tooltip("The maximum number of players per room. When a room is full, it can't be joined by new players, and so new room will be created")]
    [SerializeField]
    private byte maxPlayersPerRoom = 4;
    [Tooltip("The Ui Panel to let the user enter name, connect and play")]
    [SerializeField]
    private GameObject controlPanel;
    [Tooltip("The UI Label to inform the user that the connection is in progress")]
    [SerializeField]
    private GameObject progressLabel;

    private readonly string gameVersion = "1";
    private bool isConnecting;

    private void Awake()
    {
        PhotonNetwork.AutomaticallySyncScene = true;
    }

    private void Start()
    {
        controlPanel.SetActive(true);
        progressLabel.SetActive(false);
    }

    public void Connect()
    {
        controlPanel.SetActive(false);
        progressLabel.SetActive(true);

        if (PhotonNetwork.IsConnected)
        {
            PhotonNetwork.JoinRandomRoom();
        }
        else
        {
            isConnecting = PhotonNetwork.ConnectUsingSettings();
            PhotonNetwork.ConnectUsingSettings();
            PhotonNetwork.GameVersion = gameVersion;
        }
    }

    public override void OnConnectedToMaster()
    {
        Debug.Log("Launcher: OnConnectedToMaster() was called by PUN");

        if (isConnecting)
        {
            PhotonNetwork.JoinRandomRoom();
            isConnecting = false;
        }
    }

    public override void OnDisconnected(DisconnectCause cause)
    {
        controlPanel.SetActive(true);
        progressLabel.SetActive(false);
        isConnecting = false;
        Debug.LogWarningFormat("Launcher: OnDisconnected() was called by PUN with reason {0}", cause);
    }

    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        Debug.Log("Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
        PhotonNetwork.CreateRoom(null, new RoomOptions {MaxPlayers = maxPlayersPerRoom });
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("Launcher: OnJoinedRoom() called by PUN. Now this client is in a room.");
    }

    private void LoadArena()
    {
        if (!PhotonNetwork.IsMasterClient)
        {
            Debug.LogError("PhotonNetwork : Trying to Load a level but we are not the master Client");
        }

        Debug.LogFormat("PhotonNetwork : Loading Arena");
        PhotonNetwork.LoadLevel("SampleScene");
    }

    public override void OnPlayerEnteredRoom(Player newPlayer)
    {
        Debug.LogFormat("OnPlayerEnteredRoom() {0}", newPlayer.NickName);

        if (PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount == 2)
        {
            Debug.LogFormat("OnPlayerEnteredRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient);

            LoadArena();
        }
    }
}

I made some modification to the Launch script from the tutorial, I wanted to wait for both player to join the room before loading the scene. It’s working fine.

Here is my Game Manager script (it handles game behaviour when a player leaves the room) :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;

public class GameManager : MonoBehaviourPunCallbacks
{
    private Vector3 position;

    [Tooltip("The prefab to use for representing the player")]
    public GameObject playerPrefab;


    private void Start()
    {
        if (PhotonNetwork.IsMasterClient)
        {
            position = new Vector3(-4f, 0.5f, 9f);
        }
        else
        {
            position = new Vector3(4f, 0.5f, 9f);
        }

        if (playerPrefab == null)
        {
            Debug.LogError("<Color=Red><a>Missing</a></Color> playerPrefab Reference. Please set it up in GameObject 'Game Manager'", this);
        }
        else
        {
            PhotonNetwork.Instantiate(this.playerPrefab.name, position, Quaternion.identity, 0);
        }
    }

    public override void OnLeftRoom()
    {
        SceneManager.LoadScene(0);
    }



    public void LeaveRoom()
    {
        PhotonNetwork.LeaveRoom();
    }



    public override void OnPlayerLeftRoom(Player otherPlayer)
    {
        Debug.LogFormat("OnPlayerLeftRoom() {0}", otherPlayer.NickName);

        if (PhotonNetwork.IsMasterClient)
        {
            Debug.LogFormat("OnPlayerLeftRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient);

            LeaveRoom();
        }
    }
}

I’m asking because after many google research I only found posts where the dev forgot to link the Photon Transform View component in the Observed Components of the Photon View component, that is not my case. While doing research on the problem I also posted on Stack Overflow and the officiel Photon forums but no luck. So I don’t really know what I did wrong here.

Both player instance have different ViewIDs and RPCs work from player to player.
Here is my console log when playing :

Hi,

it’s likely because there is a script on your player that override the position of the player, for example, the component that is responsible for moving the player may still be running when it should not, make sure you disable any user input on instances of players where the photonview .isMine bool is not true.

Bye,

Jean

6 Likes

Hi,

Thank you for your response. I feel so bad now because I indeed checked photonView.IsMine before accepting input, but I accepted input if photonView.IsMine was false, and I overlooked it each time I reviewed my code.

I just changed false to true and now it’s working perfectly. I facepalmed so hard.

Anyway thank you so much, you made my day, really.

1 Like

Hi,

no worries!

Bye,

Jean

1 Like

Dude, youre a legend

1 Like

I am facing the same issue. I have added code to move player for photonView.IsMine true. Rotation is syncing properly but position of other player does not change. Plz guide how to fix this issue

Hi,

you have a character controller component, are you properly disable that when photonView.IsMine is false?

Bye.

Jean

Hello everyone!!

I’m having same problem I guess… I’m using Photon View in my Player Object.
My problem is, when I run the program, I see other player screen and other player sees my screen…
But control works fine… It’s like I am viewing other players screen yet controlling my character.

(Extremely sorry if I said anything dumb or wrong, newbie here)

I’ll give my code below

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class PlayerController : MonoBehaviour
{
    public Player playerInput;
    private CharacterController controller;
    private Transform cameraMain;
    private Vector3 playerVelocity;
    private bool groundedPlayer;
    private Transform child;
    PhotonView view;

    [SerializeField]
    private float playerSpeed = 2.0f;
    [SerializeField]
    private float gravityValue = -9.81f;
    [SerializeField]
    private float rotationSpeed = 4f;

    public void Awake()
    {
        playerInput = new Player();
        controller = GetComponent<CharacterController>();
    }
    public void OnEnable()
    {
        playerInput.Enable();
    }
    public void OnDisable()
    {
        playerInput.Disable();
    }

    private void Start()
    {
        cameraMain = Camera.main.transform;
        child = transform.GetChild(0).transform;
        view = GetComponent<PhotonView>();
    }

    void Update()
    {
        if (view.IsMine)
        {
            groundedPlayer = controller.isGrounded;
            if (groundedPlayer && playerVelocity.y < 0)
            {
                playerVelocity.y = 0f;
            }

            Vector2 movementInput = playerInput.PlayerMain.Move.ReadValue<Vector2>();
            Vector3 move = (cameraMain.forward * movementInput.y + cameraMain.right * movementInput.x);
            move.y = 0f;
            controller.Move(move * Time.deltaTime * playerSpeed);


            playerVelocity.y += gravityValue * Time.deltaTime;
            controller.Move(playerVelocity * Time.deltaTime);

            if (movementInput != Vector2.zero)
            {
                Quaternion rotation = Quaternion.Euler(new Vector3(child.localEulerAngles.x, cameraMain.localEulerAngles.y, child.localEulerAngles.z));
                child.rotation = Quaternion.Lerp(child.rotation, rotation, Time.deltaTime * rotationSpeed);
            }
        }
    }
}

hello could you explain that a bit better I’m having similar problem were I’m trying to make a vr gorilla tag fan game but the moments are not syncing. this is the video I followed
https://www.youtube.com/watch?v=KHWuTBmT1oI

Hey I have same problem here, the editor is syncing other players fine but other players can’t sync each other I don’t know what is the problem I tried to host on different devices not editor but still the editor is the only one that is syncing other players this is the player movement script:

using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class FirstPersonMovement : MonoBehaviourPun
{
    public float speed = 5;

    [Header("Running")]
    public bool canRun = true;
    public bool IsRunning { get; private set; }
    public float runSpeed = 9;
    public KeyCode runningKey = KeyCode.LeftShift;

    Rigidbody rigidbody;
    /// <summary> Functions to override movement speed. Will use the last added override. </summary>
    public List<System.Func<float>> speedOverrides = new List<System.Func<float>>();



    void Awake()
    {
        if (!photonView.IsMine) return;
        // Get the rigidbody on this.
        rigidbody = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        if (!photonView.IsMine) return;
        // Update IsRunning from input.
        IsRunning = canRun && Input.GetKey(runningKey);

        // Get targetMovingSpeed.
        float targetMovingSpeed = IsRunning ? runSpeed : speed;
        if (speedOverrides.Count > 0)
        {
            targetMovingSpeed = speedOverrides[speedOverrides.Count - 1]();
        }

        // Get targetVelocity from input.
        Vector2 targetVelocity =new Vector2( Input.GetAxis("Horizontal") * targetMovingSpeed, Input.GetAxis("Vertical") * targetMovingSpeed);

        // Apply movement.
        rigidbody.velocity = transform.rotation * new Vector3(targetVelocity.x, rigidbody.velocity.y, targetVelocity.y);
    }
}

and I made sure that the player prefab got the PhotonView and the PhotonTransformView