1
\$\begingroup\$

I am working on a multiplayer prototype and am trying to get health bars working. It's working on server side and health is working and subtracting from client side with a network variable, however I cannot get the slider to update properly.

   private void OnTriggerEnter(Collider other)
{
    if (IsServer)
    {
            if (other.GetComponent<PlayerNetworkHealth>() != null)
                other.GetComponent<PlayerNetworkHealth>().DepleteHealthClientRpc(damage);
    }         
}

  [ClientRpc]
public void DepleteHealthClientRpc(int value)
{
    if (!IsServer) return;

    health.Value -= value;


    healthBar.value = health.Value;

    if (health.Value <= 0)
        Debug.Log("Dead");

}

Any info would be appreciated. Im at a loss.

\$\endgroup\$
3
  • \$\begingroup\$ There are a couple things I would do to debug this first, Add a Debug.Log(IsServer) to check whether that's where the problem lies. It could be always false which is why nothing happens. \$\endgroup\$
    – Pow
    Feb 13 at 14:41
  • \$\begingroup\$ @Pow: I'd also want to check that other,GetComponent<PlayerNetworkHealth>() is not null before that if statement. It could turn out to actually be null, and that is the short-circuit...somehow. \$\endgroup\$ Feb 13 at 23:30
  • \$\begingroup\$ Why do you have if (!IsServer) return; in a function you want to hav executed on the client in the first place? How do you expect that to work? \$\endgroup\$
    – Zibelas
    Feb 14 at 8:36

1 Answer 1

0
\$\begingroup\$

In Mirror (and thus in Unity Networking) you can annotate simple types with SyncVar and let the library handle the syncing. In addition you can define a hook that should be executed, when the value changes. Mirror Unity (The documentation is better in Mirror for this)

[SyncVar(hook = nameof(SetHealth))]
int playerHealth = 100;

void SetHealth(int oldValue, int newValue) {
   healthBar.value = newValue;
   if (newValue <= 0)
       Debug.Log("Dead");
}

However if you are sure that the value is getting updated correctly on the client,

  if (!IsServer) return; 

does not make much sense clientside. It will simply exit your setter and can't update your slider that way.

When you are new to networking, make sure that the test device is never in host (or server) mode when you want to test client code. Since host mode is both client and server in one, it can (and will) hide a lot of mistakes you can make like not actually syncing variables. But because you are both, you can always see the correct server value.

\$\endgroup\$
3
  • \$\begingroup\$ The variables are updating like they need to, its just the slider that doesn't want to update. I got it working on the client side. Now it's just not working for the enemies. I don't know what checks to implement to update the new value. It doesn't want to use the new health.value for the healthbar.value and any IsServer or IsOwnedByServer checks don't work to update it either. I can't do IsOwner due to it being an enemy not owned by a local player. \$\endgroup\$ Feb 13 at 20:00
  • \$\begingroup\$ @WestMansionHero: One thing that might be useful for the client side is to add a log around SetHealth() indicating that it's been entered, and what the new value should be - and see if that log shows up in the client. EDIT: Or alternatively, have the SetHealth() call itself directly call an update to the UI. \$\endgroup\$ Feb 13 at 23:25
  • \$\begingroup\$ I will try that. It keeps going back and forth. Working and not working. I am now trying to enter the game through the main menu and it's not working on the client side again. I will get it fixed soon though. \$\endgroup\$ Feb 16 at 1:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .