0
\$\begingroup\$

I've been following a guide on building a 2D MMORPG, and I ran into a problem when creating a health bar for my players. I get this error message:

Could not find hook for 'CurrentHealth', hook name 'OnChangeHealth'. Method signature should be void OnChangeHealth(System.Int32 oldValue, System.Int32 newValue) (at System.Int32 Player::CurrentHealth)

Here is my code; please could someone explain to me why it is giving me this error?

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Mirror;
 
public class Player : NetworkBehaviour
{
    // We have an invetory system
    // We have action abilities, interact wit the world
    // Our stats and skill levels are here
 
 
    // Character speed variable
    public float speed;
 
 
 
    // Character Health variable | Sync Var syncs all health across the server
    public const int MaxHealth = 100;
 
 
    //Detects when a health change happens and calls the appropriate function
    [SyncVar(hook = "OnChangeHealth")]
    public int CurrentHealth = MaxHealth;
    public RectTransform healthBar;
 
 
    //Decrease the "health" of the GameObject
    public void TakeDamage(int amount)
    {
        if (!isServer)
            return;
 
        //Decrease the "health" of the GameObject
        CurrentHealth -= amount;
        //Make sure the health doesn't go below 0
        if (CurrentHealth <= 0)
        {
            CurrentHealth = 0;
        }
    }
 
 
    void Update()
    {
    // If the player is a (client)
        if (isLocalPlayer)
        {
 
    // Controls player movements
        transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * speed * Time.deltaTime);
        transform.Translate(Vector3.up * Input.GetAxis("Vertical") * speed * Time.deltaTime);
 
            if (Input.GetKeyDown(KeyCode.Space))
            {
   
                CmdTakeHealth();
            }
        }
    }
 
 
    // Updates healthBar
    void OnChangeHealth(int health)
    {
        healthBar.sizeDelta = new Vector2(health, healthBar.sizeDelta.y);
    }
 
 
    //This is a Network command, so the damage is done to the relevant GameObject
    [Command]
    void CmdTakeHealth()
    {
        //Apply damage to the GameObject
        TakeDamage(2);
    }
 
 
    public override void OnStartLocalPlayer()
    {
   // When a new player joins, run this code for the new client
        GetComponent<Renderer>().material.color = Color.blue;
    }
 
}
  ```
\$\endgroup\$
2
  • \$\begingroup\$ The error message tells you what method signature it's looking for (2 parameters). The method signature you wrote does not match this (only 1 parameter). The obvious fix would be to change your method signature to match what the error message explicitly asks you to use, no? \$\endgroup\$ Commented Aug 12, 2021 at 10:00
  • \$\begingroup\$ @DMGregory Thank you Greg, i done exactly that and it worked, i feel pretty dumb rn X_X i literally just had to read it out loud and i figured it out lol \$\endgroup\$ Commented Aug 12, 2021 at 10:07

1 Answer 1

1
\$\begingroup\$

This is one of those cases where the error message tells you exactly what you need to change. It's looking for a method with this signature:

void OnChangeHealth(System.Int32 oldValue, System.Int32 newValue) 

Note that it has two parameters: an old value, and a new value.

Compare this to the method signature that you wrote:

void OnChangeHealth(int health)

Only one parameter: the new value. You're missing the old value parameter.

These signatures do not match, so the function you wrote cannot be used directly as a hook for the SyncVar's change callback. You can fix this by adding an overload that matches the signature that the error asks for:

// Updates healthBar
void OnChangeHealth(int health)
{
    healthBar.sizeDelta = new Vector2(health, healthBar.sizeDelta.y);
}

void OnChangeHealth(int oldHealth, int newHealth)
{
    OnChangeHealth(newHealth);
}

Here I left your existing version as-is, in case you need a 1-parameter version for some other reason, and made the new 2-parameter overload just call it, discarding the unused parameter. That helps avoid code duplication, so the action happens in just one place, even if you have more than one way of initiating it.

If you don't need the 1-parameter version for anything, then you can just replace it with the 2-parameter version instead.

Moral of the story, as usual: read your error messages and take time to understand them in detail. The good ones have been carefully crafted to tell you exactly what's wrong and how to fix it.

\$\endgroup\$
1

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.