UNet SyncVar not working

Hello,

I have spent the last couple of weeks learning about the UNet API and have all my movement scripts working perfectly, but I am having a problem with getting my item script working properly.

The way I thought I needed it to work is as follows:

  • Object triggers collider TriggerEvent
  • TriggerEvent sends a command to the server
  • Server calls a RPC on all clients which changes the value of a synced variable.

The active boolean is does not change though.

public class Item : NetworkBehaviour {
	
	[SyncVar]
	public bool active = true;
	
	private void OnTriggerEnter(Collider other)
	{
		if(other.tag == "Player")
		{
			PickupItem(other.gameObject);
		}
	}
	
	public virtual void PickupItem(GameObject player)
	{
		CmdDisable ();
	}

	[Command]
	private void CmdDisable()
	{
		active = false;
		RpcDisable ();
	}

	[ClientRpc]
	private void RpcDisable()
	{
		active = false;
	}
}

You don’t need to change the variable on the client. The SyncVar changes automatically on the client when it is changed on the server. Your setup looks correct for this to happen - you perhaps should add Debug calls to ensure that the collider is working correctly.

If you want, you could add a hook on the client.

[SyncVar(hook = "OnActiveChange")]
private bool active = false;

Then when the value changes on the server, the hook is called on the client (which then takes responsibility for setting the value on the client).

private void OnActiveChange(bool updatedActive)
{
  active = updatedActive;
  Debug.Log("Active changed on client: "+active);
}

Is it possible that you are trying to change your syncVar in the editor / inspector?
As far as I have figured it out, you cannot make your syncVar changes in the inspector. At least for me, it only worked when I changed a synced variable by script.

[SyncVar]
private bool active = true;

[Server] // Might also happen in a Command
private void OnlyCalledOnServer()
{
    // Change the syncVar by script, should affect server and client(s):
    active = false;
}

I think, it works for n1gth because he uses a private variable and changes it in his code. So his answer is pretty fine, I guess. (By the way, the UNET Manual uses only private syncVars in its examples too.)

I am not sure if it is a bug or not, that it is not possible to change public syncVars in the editor. At least it is a little bit annoying because you cannot test it by changing the variable in the inspector, also not if you are using a private variable with the [SerializeField] Attribute additionally to the [SyncVar] Attribute. That is my experience with Unity 5.1.2 so far.

you need to add your script on the player which has the networkIdentity.