SyncVar Hooks not receiving updated values

The following code is attached to the player object which has a Network Identity and is marked as Local Player Authority. The host’s Thirst and Hunger values are updated correctly, but on the client the values are always what was set in the prefab.

Does anyone have an idea of what I’m doing wrong? Thanks in advance.

public class Vitals : NetworkBehaviour
{
  [SyncVar(hook = "OnHealthChange")] public float Health;
  [SyncVar(hook = "OnThirstChange")] public float Thirst;
  [SyncVar(hook = "OnHungerChange")] public float Hunger;

  public float DefaultHealth;
  public float DefaultThirst;
  public float DefaultHunger;
  public float ThirstRate;
  public float HungerRate;

  public UIUnitFrame_Bar HealthBar;
  public UIUnitFrame_Bar ThirstBar;
  public UIUnitFrame_Bar HungerBar;

  public override void OnStartLocalPlayer()
  {
    this.HealthBar = GameObject.Find("Health Bar").GetComponent<UIUnitFrame_Bar>();
    this.ThirstBar = GameObject.Find("Thirst Bar").GetComponent<UIUnitFrame_Bar>();
    this.HungerBar = GameObject.Find("Hunger Bar").GetComponent<UIUnitFrame_Bar>();

    Assert.raiseExceptions = false;
    Assert.IsNotNull(this.HealthBar, "HealthBar not set");
    Assert.IsNotNull(this.ThirstBar, "ThirstBar not set");
    Assert.IsNotNull(this.HungerBar, "HungerBar not set");

    this.HealthBar.maxValue = (int)this.DefaultHealth;
    this.ThirstBar.maxValue = (int)this.DefaultThirst;
    this.HungerBar.maxValue = (int)this.DefaultHunger;
  }
 
  [Client]
  public void FixedUpdate()
  {
    if (this.isLocalPlayer)
      CmdHeartBeat(Time.deltaTime);
  }

  [Command]
  public void CmdHeartBeat(float elapsed)
  {
    this.Thirst = this.Thirst > 0f ? this.Thirst - this.ThirstRate * elapsed : 0f;
    this.Hunger = this.Hunger > 0f ? this.Hunger - this.HungerRate * elapsed : 0f;
  }

  [Client]
  public void OnHealthChange(float value)
  {
    if (this.isLocalPlayer)
      this.HealthBar.value = (int)this.Health;
  }

  [Client]
  public void OnThirstChange(float value)
  {
    if (this.isLocalPlayer)
      this.ThirstBar.value = (int)this.Thirst;
  }

  [Client]
  public void OnHungerChange(float value)
  {
    if (this.isLocalPlayer)
      this.HungerBar.value = (int)this.Hunger;
  }
}

Why are you making your hooks Client attributes?

Slapped them on when I was getting frustrated, doesn’t make a difference.

[SyncVar(hook = “OnHealthChanged”)]
public float health = 100;

void OnHealthChanged(float hlth)
{
health = hlth;

}

try doing it like this with out your if statements as long as you got a local player setup script to designate your player scripts you dont need the islocal player check

1 Like

Hey tango,

When using the hooks, you have to actually set the value for the variable yourself. This allows you to discard information from the server if you so desire. For example,

public void OnHealthChange(float value)
{
    Health = value;
    if (this.isLocalPlayer)
        this.HealthBar.value = (int)this.Health;
}
2 Likes

@Invayne @ObliviousHarmony

Many thanks, I knew it was something dumb (isn’t it always).

Yup! Don’t know how I missed that. Guess I need to take a day or two off of looking at code. lol

1 Like