Player position not synchronizing [Photon Transform View]

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Player position not synchronizing [Photon Transform View]

jcjms
2022-07-12 17:39:46

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.

2.

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):

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:

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):

using

  • UnityEngine;

using

  • Photon.Pun;

public class

  • FirstPersonLook : MonoBehaviour

  • {

  • [SerializeField]

  • Transform character;

public float

  • sensitivity = 2;

public float

  • smoothing = 1.5f;


  • Vector2 velocity;

  • Vector2 frameVelocity;

  • PhotonView photonView;


void

  • Reset()

  • {

  • // Get the character from the FirstPersonMovement in parents.

  • character = GetComponentInParent().transform;

  • }

void

  • Start()

  • {

  • // Lock the mouse cursor to the game screen.

  • Cursor.lockState = CursorLockMode.Locked;

  • photonView = GetComponent();

  • }

void

  • Update()

  • {

if

  • (!photonView.IsMine)

  • {

  • // Get smooth velocity.

Vector2 mouseDelta = new

  • Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

  • Vector2 rawFrameVelocity = Vector2.Scale(mouseDelta, Vector2.one * sensitivity);

  • frameVelocity = Vector2.Lerp(frameVelocity, rawFrameVelocity, 1 / smoothing);

  • velocity += frameVelocity;

  • velocity.y = Mathf.Clamp(velocity.y, -90, 90);


  • // Rotate camera up-down and controller left-right from velocity.

  • transform.localRotation = Quaternion.AngleAxis(-velocity.y, Vector3.right);

  • character.localRotation = Quaternion.AngleAxis(velocity.x, Vector3.up);

  • }

  • }

  • }

FirstPersonMovement:

Code (CSharp):

using

  • System.Collections.Generic;

using

  • UnityEngine;

using

  • Photon.Pun;

  • public class FirstPersonMovement : MonoBehaviour

  • {

public float

  • speed = 5;

  • [Header("Running")]

  • public bool canRun = true;

public bool IsRunning { getprivate set

  • ; }

public float

  • runSpeed = 9;

public

  • KeyCode runningKey = KeyCode.LeftShift;

  • public GameObject bullet;

public

  • Transform firePoint;

public

  • AudioSource shootingSound;

  • PhotonView photonView;


  • Rigidbody rigidbody;

  • /// Functions to override movement speed. Will use the last added override.

public List<System.Func<float>> speedOverrides = new List<System.Func<float

  • ();

  • void Awake()

  • {

  • // Get the rigidbody on this.

  • rigidbody = GetComponent();

  • }


private void

  • Start()

  • {

  • photonView = GetComponent();

  • }


void

  • FixedUpdate()

  • {

if

  • (!photonView.IsMine)

  • {


  • // Update IsRunning from input.

  • IsRunning = canRun && Input.GetKey(runningKey);

  • // Get targetMovingSpeed.

float

  • targetMovingSpeed = IsRunning ? runSpeed : speed;

  • if (speedOverrides.Count > 0)

  • {

  • targetMovingSpeed = speedOverridesspeedOverrides.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);


  • // Shooting

if

  • (Input.GetMouseButtonDown(0))

  • {

  • Instantiate(bullet, firePoint.position, firePoint.rotation);

  • shootingSound.Play();

  • }

  • }

  • /// Update IsRunning from input.*

  • IsRunning = canRun && Input.GetKey(runningKey);

  • // Get targetMovingSpeed.

  • float targetMovingSpeed = IsRunning ? runSpeed : speed;

  • if (speedOverrides.Count > 0)

  • {

  • targetMovingSpeed = speedOverridesspeedOverrides.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);

  • // Shooting

  • if(Input.GetMouseButtonDown(0))

  • {

  • Instantiate(bullet, firePoint.position, firePoint.rotation);

  • shootingSound.Play();

  • }/*

  • }

  • }

Jump:

Code (CSharp):

using

  • UnityEngine;

using

  • Photon.Pun;

public class

  • Jump : MonoBehaviour

  • {

  • Rigidbody rigidbody;

public float

  • jumpStrength = 2;

public event

  • System.Action Jumped;

  • [SerializeField, Tooltip("Prevents jumping when the transform is in mid-air.")]

  • GroundCheck groundCheck;

  • PhotonView photonView;

  • void Reset()

  • {

  • // Try to get groundCheck.

  • groundCheck = GetComponentInChildren();

  • }


void

  • Awake()

  • {

  • // Get rigidbody.

  • rigidbody = GetComponent();

  • }

private void

  • Start()

  • {

  • photonView = GetComponent();

  • }

void

  • LateUpdate()

  • {

if

  • (!photonView.IsMine)

  • {

  • // Jump when the Jump button is pressed and we are on the ground.

if

  • (Input.GetButtonDown("Jump") && (!groundCheck || groundCheck.isGrounded))

  • {

  • rigidbody.AddForce(Vector3.up * 100 * jumpStrength);

  • Jumped?.Invoke();

  • }

  • }

  • }

  • }


Crouch:

Code (CSharp):

using

  • UnityEngine;

using

  • Photon.Pun;

public class

  • Crouch : MonoBehaviour

  • {

public

  • KeyCode key = KeyCode.LeftControl;

  • [Header("Slow Movement")]

  • [Tooltip("Movement to slow down when crouched.")]

  • public FirstPersonMovement movement;

  • [Tooltip("Movement speed when crouched.")]

public float

  • movementSpeed = 2;

  • [Header("Low Head")]

  • [Tooltip("Head to lower when crouched.")]

public

  • Transform headToLower;

  • [HideInInspector]

public float

  • ? defaultHeadYLocalPosition;

public float

  • crouchYHeadPosition = 1;


  • [Tooltip("Collider to lower when crouched.")]

public

  • CapsuleCollider colliderToLower;

  • [HideInInspector]

public float

  • ? defaultColliderHeight;


public bool IsCrouched { getprivate set

  • ; }

public event

  • System.Action CrouchStart, CrouchEnd;

  • PhotonView photonView;


void

  • Reset()

  • {

  • // Try to get components.

  • movement = GetComponentInParent();

  • headToLower = movement.GetComponentInChildren().transform;

  • colliderToLower = movement.GetComponentInChildren();

  • }

private void

  • Start()

  • {

  • photonView = GetComponent();

  • }

void

  • LateUpdate()

  • {

if

  • (!photonView.IsMine)

  • {

if

  • (Input.GetKey(key))

  • {


  • // Enforce a low head.

if

  • (headToLower)

  • {

  • // If we don't have the defaultHeadYLocalPosition, get it now.

if

  • (!defaultHeadYLocalPosition.HasValue)

  • {

  • defaultHeadYLocalPosition = headToLower.localPosition.y;

  • }

  • // Lower the head.

headToLower.localPosition =new

  • Vector3(headToLower.localPosition.x, crouchYHeadPosition, headToLower.localPosition.z);

  • }

  • // Enforce a low colliderToLower.

if

  • (colliderToLower)

  • {

  • // If we don't have the defaultColliderHeight, get it now.

if

  • (!defaultColliderHeight.HasValue)

  • {

  • defaultColliderHeight = colliderToLower.height;

  • }

  • // Get lowering amount.

float

  • loweringAmount;

if

  • (defaultHeadYLocalPosition.HasValue)

  • {

loweringAmount = defaultHeadYLocalPosition.Value

  • - crouchYHeadPosition;

  • }

  • else

  • {

  • loweringAmount = defaultColliderHeight.Value * .5f;

  • }

  • // Lower the colliderToLower.

colliderToLower.height = Mathf.Max(defaultColliderHeight.Value

  • - loweringAmount, 0);

  • colliderToLower.center = Vector3.up * colliderToLower.height * .5f;

  • }

  • // Set IsCrouched state.

if

  • (!IsCrouched)

  • {

IsCrouched = true

  • ;

SetSpeedOverrideActive(true

  • );

  • CrouchStart?.Invoke();

  • }

  • }

  • else

  • {

if

  • (IsCrouched)

  • {


  • // Rise the head back up.

if

  • (headToLower)

  • {

headToLower.localPosition = new Vector3(headToLower.localPosition.x, defaultHeadYLocalPosition.Value

  • , headToLower.localPosition.z);

  • }


  • // Reset the colliderToLower's height.

if

  • (colliderToLower)

  • {

colliderToLower.height = defaultColliderHeight.Value

  • ;

  • colliderToLower.center = Vector3.up * colliderToLower.height * .5f;

  • }

  • // Reset IsCrouched.

IsCrouched = false

  • ;

  • SetSpeedOverrideActive(false);

  • CrouchEnd?.Invoke();

  • }

  • }

  • }

  • }

  • #region Speed override.

void SetSpeedOverrideActive(bool

  • state)

  • {

  • // Stop if there is no movement component.

if

  • (!movement)

  • {

return

  • ;

  • }

  • // Update SpeedOverride.

if

  • (state)

  • {


  • // Try to add the SpeedOverride to the movement component.

if

  • (!movement.speedOverrides.Contains(SpeedOverride))

  • {

movement.speedOverrides.Add

  • (SpeedOverride);

  • }

  • }

  • else

  • {

  • // Try to remove the SpeedOverride from the movement component.

if

  • (movement.speedOverrides.Contains(SpeedOverride))

  • {

movement.speedOverrides.Remove

  • (SpeedOverride);

  • }

  • }

  • }


float

  • SpeedOverride() => movementSpeed;

  • #endregion

  • }

I think that should be enough. If anything else is needed just let me know.

Thank you for helping me!

Kind regards, jcjms.

Comments

Tobias
2022-07-14 14:50:40

The PUN Basics Tutorial is about getting characters synchronized. Check it out for a reference.

jcjms
2022-07-15 08:58:00

Solved it my self somehow, don't know how, but it works now. Thank you for answering. Kind regards.

Back to top