Mirror/doc/Guides/Sync/SyncVarHook.md
vis2k b9f52fdb46
breaking: fix: #1151 - assign SyncVars before calling the Hook. Hook now passes old and new value instead of changing it from new value to old value, as this would break all SyncVar Hook projects silently. (#1416)
* test

* new docs

* adjust CheckForHookFunction to expect two hooks

* update example

* update example

* update example

* update test

* update example

* SyncVar.set: store value in oldValue variable

* SyncVar.set: pass old value to hook too

* TODO

* SyncVar deserialize store value in oldValue variable (for simple types)

* SyncVar deserialize: pass old value to hook too (for simple types)

* add test for GameObject type

* fix comment

* SyncVar deserialize: set value before calling hook

* add TODO

* SyncVar.set: set value before calling hook

* replace tests

* GO test

* SyncVar deserialize: move oldvalue code higher up so it applies to GO/NI too

* syntax

* SyncVar deserialize: pass oldValue to hook (GO/NI types)

* SyncVar deserialize: set netid before calling hook (GO/NI types)

* update comment

* update comment

* update comment

* shorter

* comment, TODO

* put oldValue code into separate cases again

* fix SyncVarEqual comparing the same two __goNetId values

* get rid of tmpValue

* fix weaver tests

* remove TODO

* SyncVar deserialize simple types: get rid of tmpValue here too

* remove tests
2020-01-10 16:17:13 +01:00

1.6 KiB

SyncVar Hook

SyncVar hook video tutorial

The hook attribute can be used to specify a function to be called when the SyncVar changes value on the client. This ensures that all clients receive the proper variables from other clients.

  • The Hook method must have a two parameters of the same type as the SyncVar property. One for the old value, one for the new value.
  • The Hook is always called after the value was set. You don't need to set it yourself.

Below is a simple example of assigning a random color to each player when they're spawned on the server. All clients will see all players in the correct colors, even if they join later.

using UnityEngine;
using UnityEngine.Networking;

public class PlayerController : NetworkBehaviour
{

    [SyncVar(hook = nameof(SetColor))]
    Color playerColor = Color.black;

    // Unity makes a clone of the Material every time GetComponent<Renderer>().material is used.
    // Cache it here and Destroy it in OnDestroy to prevent a memory leak.
    Material cachedMaterial;

    public override void OnStartServer()
    {
        base.OnStartServer();
        playerColor = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
    }

    void SetColor(Color oldColor, Color newColor)
    {
        if (cachedMaterial == null)
            cachedMaterial = GetComponent<Renderer>().material;

        cachedMaterial.color = newColor;
    }

    void OnDestroy()
    {
        Destroy(cachedMaterial);
    }
}