Why Aren't Game Object Positions Synced?

I have a game object that the player can move around with this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickUpItems : MonoBehaviour {

public Transform  throwables;
public PhotonView photonView;
public GameObject itemPos;
public GameObject item;
public Rigidbody  itemRB;
public bool 	  hasItem;
public RaycastHit hit;
public int 		  rayDist;
public int 		  power;

public void Update() {

	//Try to pick up item if player doesn't already have one and clicks
	if(Input.GetButtonDown("Fire1") && hasItem == false) {

		//Check for a throwable object
		Physics.Raycast(this.transform.position, this.transform.forward, out hit, rayDist, 1 << 8);

		if(hit.collider != null) {

			//Pick up object
			item = hit.collider.transform.gameObject.transform.parent.gameObject;
			item.transform.parent = itemPos.transform;
			item.transform.position = itemPos.transform.position;

			itemRB = item.GetComponent<Rigidbody>();
			itemRB.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionX;
			hasItem = true;

			//Transfer PhotonView
			photonView = item.GetComponent<PhotonView>();
			photonView.TransferOwnership(PhotonNetwork.player);
		}

		//Throw item if player has one and clicks
		} else if(Input.GetButtonDown("Fire1") && hasItem == true) {
			item.transform.parent = throwables;

			itemRB.AddForce(this.transform.forward * power, ForceMode.Impulse);
			itemRB.constraints = RigidbodyConstraints.None;
			hasItem = false;
		}
	}
}
I've experimented using different settings for the Photon View and Photon Transform View components on the game object that I'm trying to move. It moves perfectly fine for the player that's moving it however it has a weird affect for other players in the same room. The object just falls through the ground endlessly. Why does this happen?

Answers

  • Hi @YBtheS,

    since the object has an attached Rigidbody component, the problem probably is, that only the client, who interacts with the object, sets it's constraints. Settings those constraints, the object's position is frozen on one client but not on the other client(s). Changing those constraints have to be synchronized. In this case this can be done by using a RPC for example.
  • Hi @YBtheS,

    since the object has an attached Rigidbody component, the problem probably is, that only the client, who interacts with the object, sets it's constraints. Settings those constraints, the object's position is frozen on one client but not on the other client(s). Changing those constraints have to be synchronized. In this case this can be done by using a RPC for example.

    Thanks for the help. I tried doing that and my new script looks like this:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PickUpItems : MonoBehaviour {
    
    	public Transform  throwables;
    	public PhotonView photonView;
    	public PhotonView thisPhotonView;
    	public GameObject itemPos;
    	public GameObject item;
    	public Rigidbody  itemRB;
    	public bool 	  hasItem;
    	public RaycastHit hit;
    	public int 		  rayDist;
    	public int 		  power;
    
    	void Awake() {
    		Debug.Log(thisPhotonView);
    	}
    
    	void Update() {
    
    		//Try to pick up item if player doesn't already have one and clicks
    		if(thisPhotonView.isMine && Input.GetButtonDown("Fire1") && hasItem == false) {
    
    			//Check for a throwable object
    			Physics.Raycast(this.transform.position, this.transform.forward, out hit, rayDist, 1 << 8);
    
    			if(hit.collider != null) {
    
    				//Pick up object
    				item = hit.collider.transform.gameObject.transform.parent.gameObject;
    				item.transform.parent = itemPos.transform;
    				item.transform.position = itemPos.transform.position;
    
    				itemRB = item.GetComponent<Rigidbody>();
    				//itemRB.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionX;
    				hasItem = true;
    				thisPhotonView.RPC("ToggleConstraints", PhotonTargets.All, true);
    
    				//Transfer PhotonView
    				photonView = item.GetComponent<PhotonView>();
    				photonView.TransferOwnership(PhotonNetwork.player);
    			}
    
    		//Throw item if player has one and clicks
    		} else if(thisPhotonView.isMine && Input.GetButtonDown("Fire1") && hasItem == true) {			
    			item.transform.parent = throwables;
    
    			itemRB.AddForce(this.transform.forward * power, ForceMode.Impulse);
    			//itemRB.constraints = RigidbodyConstraints.None;
    			hasItem = false;
    			thisPhotonView.RPC("ToggleConstraints", PhotonTargets.All, false);
    		}
    	}
    
    	[PunRPC]
    	void ToggleConstraints(bool freeze) {
    		if(freeze) {
    			gameObject.GetComponent<PickUpItems>().itemRB.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionX;
    		} else {
    			itemRB.constraints = RigidbodyConstraints.None;
    			//Note that I wrote the previous if statement without the gameObject.GetComponent<PickUpItems>() bit but I got the same error.
    		}
    	}
    
    	void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
    		//Nothing
    	}
    }
    
    When I test it out with two players, one can pick up a game object perfectly fine however the other player gets the error following error:
    UnassignedReferenceException: The variable itemRB of PickUpItems has not been assigned.
    You probably need to assign the itemRB variable of the PickUpItems script in the inspector.
    PickUpItems.ToggleConstraints (Boolean freeze) (at Assets/[2]Scripts/PickUpItems.cs:88)
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
    Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
    System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
    NetworkingPeer.ExecuteRpc (ExitGames.Client.Photon.Hashtable rpcData, Int32 senderID) (at Assets/Plugins/PhotonNetwork/NetworkingPeer.cs:3007)
    NetworkingPeer.OnEvent (ExitGames.Client.Photon.EventData photonEvent) (at Assets/Plugins/PhotonNetwork/NetworkingPeer.cs:2601)
    ExitGames.Client.Photon.PeerBase.DeserializeMessageAndCallback (System.Byte[] inBuff)
    ExitGames.Client.Photon.EnetPeer.DispatchIncomingCommands ()
    ExitGames.Client.Photon.PhotonPeer.DispatchIncomingCommands ()
    PhotonHandler.Update () (at Assets/Plugins/PhotonNetwork/PhotonHandler.cs:158)


    Why is that?
  • YBtheS
    YBtheS
    edited August 2018
    Note that I just used OnPhotonSerializeView because I need to to use the Photon View with this script I think.
  • The error message states that you don't have assigned something to the itemRB variable. To do so, you can add itemRB = item.GetComponent<Rigidbody>(); to the Awake or Start function. Having this, you can remove the same line from the Update function. Currently only the client, who interacts with the object, sets this reference properly and the other clients fail when accessing it.
  • The error message states that you don't have assigned something to the itemRB variable. To do so, you can add itemRB = item.GetComponent<Rigidbody>(); to the Awake or Start function. Having this, you can remove the same line from the Update function. Currently only the client, who interacts with the object, sets this reference properly and the other clients fail when accessing it.

    I can't do that since item constantly changes so I need to update the rigidbody.
  • Anybody have any ideas?
  • @YBtheS !) Check if you have gave reference to itemRB in the inspector ( UnassignedReferenceException comes when you have not assigned anything to itemRB variable
  • Romin said:

    @YBtheS !) Check if you have gave reference to itemRB in the inspector ( UnassignedReferenceException comes when you have not assigned anything to itemRB variable

    Thanks. I realized that it is not assigned in the inspector. But item surely has a rigidbody so that's strange. I'm not exactly sure why that is happening.