Hi, so i’m new to Unity and coding in general. I am currently trying to make a 2D Platformer with some RPG elements. I’m also trying to expand on BlackThornProds inventory system tutorial script. However everytime I click on my health item my currentHealth remains the same
Here is the player health script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IgorHealth : MonoBehaviour
{
public int maxHealth = 100;
public int currentHealth;
public HealthBar healthBar;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
}
// Update is called once per frame
void Update()
{
if (currentHealth>0 && currentHealth < maxHealth)
{
if (Input.GetKeyDown(KeyCode.Q))
{
TakeDamage(10);
}
}
}
void TakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
}
And this is the script that I am using for the health Item:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthAddButton : MonoBehaviour
{
private IgorHealth igorHealth;
public int healthBoost = 30;
private void Start()
{
igorHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<IgorHealth>();
}
public void Use()
{
if (igorHealth.currentHealth < igorHealth.maxHealth)
{
igorHealth.currentHealth += healthBoost;
Destroy(gameObject);
}
}
}
Try placing debug.log(igorHealth.currentHealth); in the Use Method, and then use the button. If you can a console log then it’s working but you just haven’t updated healthBar.SetHealth(currentHealth); in the Use method.
You do not appear to be invoking any method when the button is pressed.
There are two options. When you select the button, in the inspector window, there is an OnClick function. You can manually drag and drop the gameobject that has the script you need into the reference slot, and then select the required method from the script.
Select the button in the hierarchy
Look for the On Click ()
Press the plus sign and drag the button into the reference slot. From the dropdown select the “Use” method. This will invoke the “Use” method when you press the button.
(This is based on the assumption you have that script attached to the button from what you code looks like)
You could also probably do this in start:
// when the button this script is attached to is pressed, invoke the "Use" method.
gameObject.onClick.AddListener(Use);
Although I’m not sure if that would work. “gameObject” is a reference to self (again, I assume you have the script attached to the button from the looks of your code) so if the “self” reference is a button I don’t see why not.
Thanks for replying, The button works fine. The thing is that I’m unable to refer to the HealthBar script to use the SetHealth method inside it.
The HealthBar script is attached to an image inside a Canvas of tag PlayerUI.
Edit: The HealthAddButton script is inside a Health Button prefab which is currently not in the scene, so how do I call the HealthBar script in the HealthAddButton script?
A)Assuming HealthBar is always in scene like the player then you can use GameObject.FindWithTag("PlayerUI") in class HealthAddButton script like you did with player and reference that instead (Note: FindWithTag returns “one active GameObject tagged”) So don’t use if you have multiple GameObject.
Place FindWithTag anywhere besides Update() or FixedUpdate() (or anywhere that will run every frame) for performance issue.
B)If above isn’t possible then try to create an EventHandler system.
Basically options:
1 - HealthAddButton pressed anywhere in game → IgorHealth script gets notify → make changes to UI
Below is example:
//HealthAddButton script
public delegate void HPIncrease();
public static event HPIncrease hpIncreased;
void Use() {
//Your original code
//Call event to notify all listener that something is used!
hpIncrease();
}
C) Scriptable Object stores data for you to use. So you can create an instance SO of IgorStats. There are many tutorial on using this for player health! I haven’t implement it for health before but it works as a save system for me.
Sorry, for the late response. I was knee deep into finishing my school assignments but I did keep checking back on this thread every now and then.
So I tried to do what you told me. Since A) didn’t work out for me, I decided to test out B). I have never worked with an Event Handler system before so I decided to watch a few tutorials on events and delegates in c#, but they went over my head.
So I followed your example and made the following changes to my code:
HealthAddButton script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthAddButton : MonoBehaviour
{
private IgorHealth igorHealth;
public int healthBoost = 30;
public delegate void HPIncrease();
public static event HPIncrease hpIncrease;
private void Start()
{
igorHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<IgorHealth>();
}
public void Use()
{
if (igorHealth.currentHealth < igorHealth.maxHealth)
{
igorHealth.currentHealth += healthBoost;
Destroy(gameObject);
hpIncrease();
}
}
}
IgorHealth Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IgorHealth : MonoBehaviour
{
public int maxHealth = 100;
public int currentHealth;
public HealthBar healthBar;
public HealthAddButton healthAddButton;
public IgorInvincible igorInvincible;
public int healthBoost = 30;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
}
// Update is called once per frame
void Update()
{
if (currentHealth>0 || currentHealth < maxHealth)
{
if (igorInvincible.currentInvincibleTime > 0)
{
TakeDamage(0);
} else
{
if (Input.GetKeyDown(KeyCode.Q))
{
TakeDamage(10);
}
}
}
if (Input.GetKeyDown(KeyCode.Z))
{
AddHealth();
}
}
void TakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
void AddHealth()
{
currentHealth += healthBoost;
healthBar.SetHealth(currentHealth);
}
void OnEnabled()
{
HealthAddButton.hpIncrease += UsedIsClicked;
}
void OnDisable()
{
HealthAddButton.hpIncrease -= UsedIsClicked;
}
void UsedIsClicked()
{
healthBar.SetHealth(currentHealth);
}
}
It means when HealthAddButton.Use() is called, it is calling nothing. Since it’s pointing to nothing, it’ll throw a NullReferenceExeception. Try placing the line before you destroy the gameObject.