Search Unity

Third Party Player position not synchronizing [Photon Transform View]

Discussion in 'Multiplayer' started by jcjms, Jul 12, 2022.

  1. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    Dear communty, I've been programming a photon multiplayer game in unity for a few days. When I create a room I can't move until a second player joins (but that doesn't matter for now). The real problem comes when a second player joins. The player controller for the second player is spawned and I can move freely, but my movement change is not displayed on the other player's screen. There I just stand still, although I have already moved a long way.

    Here are 2 pictures of my player prefab:

    1.
    Playercontroller.png

    2.
    Playercontroller2.png

    And yes, I noticed it too. There are two transform views on the prefab (classic and normal) but one is disabled. In that respect it shouldn't be a problem. It didn't work even with just one.

    Here is a screenshot of my first person camera (I think the error is somewhere here):
    Camera.png

    I've added the photon view here again because the 'First Person Look Script' checks 'if (!photonView.IsMine)' again. And if I hadn't attached the Photon view I would of course get a NullReferenceException. I think thats the error, but how should I do it if not like this?

    Here is a picture of the hierarchy of my prefab:
    Hierarchy.png

    I got the base of the player controller from the unity asset store (https://assetstore.unity.com/packages/tools/input-management/mini-first-person-controller-174710).

    Here are some of the player controller scripts that might be useful:

    FirstPersonLook:
    Code (CSharp):
    1. using UnityEngine;
    2. using Photon.Pun;
    3.  
    4. public class FirstPersonLook : MonoBehaviour
    5. {
    6.     [SerializeField]
    7.     Transform character;
    8.     public float sensitivity = 2;
    9.     public float smoothing = 1.5f;
    10.  
    11.     Vector2 velocity;
    12.     Vector2 frameVelocity;
    13.  
    14.     PhotonView photonView;
    15.  
    16.     void Reset()
    17.     {
    18.         // Get the character from the FirstPersonMovement in parents.
    19.         character = GetComponentInParent<FirstPersonMovement>().transform;
    20.     }
    21.  
    22.     void Start()
    23.     {
    24.         // Lock the mouse cursor to the game screen.
    25.         Cursor.lockState = CursorLockMode.Locked;
    26.         photonView = GetComponent<PhotonView>();
    27.     }
    28.  
    29.     void Update()
    30.     {
    31.         if (!photonView.IsMine)
    32.         {
    33.             // Get smooth velocity.
    34.             Vector2 mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
    35.             Vector2 rawFrameVelocity = Vector2.Scale(mouseDelta, Vector2.one * sensitivity);
    36.             frameVelocity = Vector2.Lerp(frameVelocity, rawFrameVelocity, 1 / smoothing);
    37.             velocity += frameVelocity;
    38.             velocity.y = Mathf.Clamp(velocity.y, -90, 90);
    39.  
    40.             // Rotate camera up-down and controller left-right from velocity.
    41.             transform.localRotation = Quaternion.AngleAxis(-velocity.y, Vector3.right);
    42.             character.localRotation = Quaternion.AngleAxis(velocity.x, Vector3.up);
    43.         }
    44.     }
    45. }
    46.  
    FirstPersonMovement:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using Photon.Pun;
    4.  
    5. public class FirstPersonMovement : MonoBehaviour
    6. {
    7.     public float speed = 5;
    8.  
    9.     [Header("Running")]
    10.     public bool canRun = true;
    11.     public bool IsRunning { get; private set; }
    12.     public float runSpeed = 9;
    13.     public KeyCode runningKey = KeyCode.LeftShift;
    14.  
    15.     public GameObject bullet;
    16.     public Transform firePoint;
    17.     public AudioSource shootingSound;
    18.  
    19.     PhotonView photonView;
    20.  
    21.     Rigidbody rigidbody;
    22.     /// <summary> Functions to override movement speed. Will use the last added override. </summary>
    23.     public List<System.Func<float>> speedOverrides = new List<System.Func<float>>();
    24.  
    25.     void Awake()
    26.     {
    27.         // Get the rigidbody on this.
    28.         rigidbody = GetComponent<Rigidbody>();
    29.     }
    30.  
    31.     private void Start()
    32.     {
    33.         photonView = GetComponent<PhotonView>();
    34.     }
    35.  
    36.     void FixedUpdate()
    37.     {  
    38.         if (!photonView.IsMine)
    39.         {
    40.             // Update IsRunning from input.
    41.             IsRunning = canRun && Input.GetKey(runningKey);
    42.  
    43.             // Get targetMovingSpeed.
    44.             float targetMovingSpeed = IsRunning ? runSpeed : speed;
    45.             if (speedOverrides.Count > 0)
    46.             {
    47.                 targetMovingSpeed = speedOverrides[speedOverrides.Count - 1]();
    48.             }
    49.  
    50.             // Get targetVelocity from input.
    51.             Vector2 targetVelocity =new Vector2( Input.GetAxis("Horizontal") * targetMovingSpeed, Input.GetAxis("Vertical") * targetMovingSpeed);
    52.  
    53.             // Apply movement.
    54.             rigidbody.velocity = transform.rotation * new Vector3(targetVelocity.x, rigidbody.velocity.y, targetVelocity.y);
    55.  
    56.             // Shooting
    57.             if(Input.GetMouseButtonDown(0))
    58.             {
    59.                 Instantiate(bullet, firePoint.position, firePoint.rotation);
    60.                 shootingSound.Play();
    61.             }
    62.         }
    63.        
    64.         /*// Update IsRunning from input.
    65.         IsRunning = canRun && Input.GetKey(runningKey);
    66.  
    67.         // Get targetMovingSpeed.
    68.         float targetMovingSpeed = IsRunning ? runSpeed : speed;
    69.         if (speedOverrides.Count > 0)
    70.         {
    71.             targetMovingSpeed = speedOverrides[speedOverrides.Count - 1]();
    72.         }
    73.  
    74.         // Get targetVelocity from input.
    75.         Vector2 targetVelocity =new Vector2( Input.GetAxis("Horizontal") * targetMovingSpeed, Input.GetAxis("Vertical") * targetMovingSpeed);
    76.  
    77.         // Apply movement.
    78.         rigidbody.velocity = transform.rotation * new Vector3(targetVelocity.x, rigidbody.velocity.y, targetVelocity.y);
    79.  
    80.         // Shooting
    81.         if(Input.GetMouseButtonDown(0))
    82.         {
    83.             Instantiate(bullet, firePoint.position, firePoint.rotation);
    84.             shootingSound.Play();
    85.         }*/
    86.     }
    87. }
    Jump:
    Code (CSharp):
    1. using UnityEngine;
    2. using Photon.Pun;
    3.  
    4. public class Jump : MonoBehaviour
    5. {
    6.     Rigidbody rigidbody;
    7.     public float jumpStrength = 2;
    8.     public event System.Action Jumped;
    9.  
    10.     [SerializeField, Tooltip("Prevents jumping when the transform is in mid-air.")]
    11.     GroundCheck groundCheck;
    12.  
    13.     PhotonView photonView;
    14.  
    15.     void Reset()
    16.     {
    17.         // Try to get groundCheck.
    18.         groundCheck = GetComponentInChildren<GroundCheck>();
    19.     }
    20.  
    21.     void Awake()
    22.     {
    23.         // Get rigidbody.
    24.         rigidbody = GetComponent<Rigidbody>();
    25.     }
    26.  
    27.     private void Start()
    28.     {
    29.         photonView = GetComponent<PhotonView>();
    30.     }
    31.  
    32.     void LateUpdate()
    33.     {
    34.         if (!photonView.IsMine)
    35.         {
    36.             // Jump when the Jump button is pressed and we are on the ground.
    37.             if (Input.GetButtonDown("Jump") && (!groundCheck || groundCheck.isGrounded))
    38.             {
    39.                 rigidbody.AddForce(Vector3.up * 100 * jumpStrength);
    40.                 Jumped?.Invoke();
    41.             }
    42.         }
    43.     }
    44. }
    45.  
    Crouch:
    Code (CSharp):
    1. using UnityEngine;
    2. using Photon.Pun;
    3.  
    4. public class Crouch : MonoBehaviour
    5. {
    6.     public KeyCode key = KeyCode.LeftControl;
    7.  
    8.     [Header("Slow Movement")]
    9.     [Tooltip("Movement to slow down when crouched.")]
    10.     public FirstPersonMovement movement;
    11.     [Tooltip("Movement speed when crouched.")]
    12.     public float movementSpeed = 2;
    13.  
    14.     [Header("Low Head")]
    15.     [Tooltip("Head to lower when crouched.")]
    16.     public Transform headToLower;
    17.     [HideInInspector]
    18.     public float? defaultHeadYLocalPosition;
    19.     public float crouchYHeadPosition = 1;
    20.    
    21.     [Tooltip("Collider to lower when crouched.")]
    22.     public CapsuleCollider colliderToLower;
    23.     [HideInInspector]
    24.     public float? defaultColliderHeight;
    25.  
    26.     public bool IsCrouched { get; private set; }
    27.     public event System.Action CrouchStart, CrouchEnd;
    28.  
    29.     PhotonView photonView;
    30.  
    31.     void Reset()
    32.     {
    33.         // Try to get components.
    34.         movement = GetComponentInParent<FirstPersonMovement>();
    35.         headToLower = movement.GetComponentInChildren<Camera>().transform;
    36.         colliderToLower = movement.GetComponentInChildren<CapsuleCollider>();
    37.     }
    38.  
    39.     private void Start()
    40.     {
    41.         photonView = GetComponent<PhotonView>();
    42.     }
    43.  
    44.     void LateUpdate()
    45.     {  
    46.         if (!photonView.IsMine)
    47.         {
    48.             if (Input.GetKey(key))
    49.             {
    50.                 // Enforce a low head.
    51.                 if (headToLower)
    52.                 {
    53.                     // If we don't have the defaultHeadYLocalPosition, get it now.
    54.                     if (!defaultHeadYLocalPosition.HasValue)
    55.                     {
    56.                         defaultHeadYLocalPosition = headToLower.localPosition.y;
    57.                     }
    58.  
    59.                     // Lower the head.
    60.                     headToLower.localPosition = new Vector3(headToLower.localPosition.x, crouchYHeadPosition, headToLower.localPosition.z);
    61.                 }
    62.  
    63.                 // Enforce a low colliderToLower.
    64.                 if (colliderToLower)
    65.                 {
    66.                     // If we don't have the defaultColliderHeight, get it now.
    67.                     if (!defaultColliderHeight.HasValue)
    68.                     {
    69.                         defaultColliderHeight = colliderToLower.height;
    70.                     }
    71.  
    72.                     // Get lowering amount.
    73.                     float loweringAmount;
    74.                     if(defaultHeadYLocalPosition.HasValue)
    75.                     {
    76.                         loweringAmount = defaultHeadYLocalPosition.Value - crouchYHeadPosition;
    77.                     }
    78.                     else
    79.                     {
    80.                         loweringAmount = defaultColliderHeight.Value * .5f;
    81.                     }
    82.  
    83.                     // Lower the colliderToLower.
    84.                     colliderToLower.height = Mathf.Max(defaultColliderHeight.Value - loweringAmount, 0);
    85.                     colliderToLower.center = Vector3.up * colliderToLower.height * .5f;
    86.                 }
    87.  
    88.                 // Set IsCrouched state.
    89.                 if (!IsCrouched)
    90.                 {
    91.                     IsCrouched = true;
    92.                     SetSpeedOverrideActive(true);
    93.                     CrouchStart?.Invoke();
    94.                 }
    95.             }
    96.             else
    97.             {
    98.                 if (IsCrouched)
    99.                 {
    100.                     // Rise the head back up.
    101.                     if (headToLower)
    102.                     {
    103.                         headToLower.localPosition = new Vector3(headToLower.localPosition.x, defaultHeadYLocalPosition.Value, headToLower.localPosition.z);
    104.                     }
    105.  
    106.                     // Reset the colliderToLower's height.
    107.                     if (colliderToLower)
    108.                     {
    109.                         colliderToLower.height = defaultColliderHeight.Value;
    110.                         colliderToLower.center = Vector3.up * colliderToLower.height * .5f;
    111.                     }
    112.  
    113.                     // Reset IsCrouched.
    114.                     IsCrouched = false;
    115.                     SetSpeedOverrideActive(false);
    116.                     CrouchEnd?.Invoke();
    117.                 }
    118.             }
    119.         }
    120.     }
    121.  
    122.  
    123.     #region Speed override.
    124.     void SetSpeedOverrideActive(bool state)
    125.     {
    126.         // Stop if there is no movement component.
    127.         if(!movement)
    128.         {
    129.             return;
    130.         }
    131.  
    132.         // Update SpeedOverride.
    133.         if (state)
    134.         {
    135.             // Try to add the SpeedOverride to the movement component.
    136.             if (!movement.speedOverrides.Contains(SpeedOverride))
    137.             {
    138.                 movement.speedOverrides.Add(SpeedOverride);
    139.             }
    140.         }
    141.         else
    142.         {
    143.             // Try to remove the SpeedOverride from the movement component.
    144.             if (movement.speedOverrides.Contains(SpeedOverride))
    145.             {
    146.                 movement.speedOverrides.Remove(SpeedOverride);
    147.             }
    148.         }
    149.     }
    150.  
    151.     float SpeedOverride() => movementSpeed;
    152.     #endregion
    153. }
    154.  
    I think that should be enough. If anything else is needed just let me know :).

    Thank you for helping me!

    Kind regards, jcjms.
     
  2. toddkc

    toddkc

    Joined:
    Nov 20, 2016
    Posts:
    207
    This is pretty basic stuff, honestly. There are tons and tons of beginner PUN tutorials on youtube, find one and follow it. One big issue I see is you keep checking that the photon view is NOT the local player with
    Code (CSharp):
    1. !photonView.IsMine
     
    tobiass likes this.
  3. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    Hello, first of all thanks for answering my question :)! I removed the exclamation mark. But now I control the other player and not my own! That was the first thing I tried. Or did I misunderstand your answer?
    Kind regards, jcjms : D
     
  4. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    Ok so, after experimenting a bit and only leaving the exclamation mark on the PlayerLook script (which seemed the most logical to me). Surprisingly, I had the same result, only this time only the player didn't move before a second one joined. What am I doing wrong?
     
  5. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    I followed a tutorial. Checked everything 3 times. No hint of an answer. That's why I'm asking here.
     
  6. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    Is there a way to determine that if photonView.IsMine is true in the Movement script, the camera is packed right away (without checking again in the PlayerLook script)? Because the problem seems to be that the camera is always assigned to the wrong player... Or is there a simpler solution?

    EDIT: But the PlayerLook script works on the other player (or at least the other player turns, if I move my mouse). Just the camera itself is on the wrong player. But camera and player look are controlled by the same script. The PlayerLook script is assigned to the camera element. tf? I don't get it.
     
    Last edited: Jul 13, 2022
  7. jcjms

    jcjms

    Joined:
    Jul 24, 2018
    Posts:
    14
    Solved it my self somehow, don't know how, but it works now. Thank you for answering. Kind regards.