Hi I think these have been some very good lectures and examples on using unity events, I do however think its a bit messy for the use case with what we’re using them for.
Here’s an alternative, in Health.cs make the following changes:
public event Action<float> OnTakeDamage;
In the method that is called for taking damage invoke the event by adding:
if (OnTakeDamage != null)
{
OnTakeDamage(damage);
}
Then add the following class onto the damagetext spawner that also spawns the canvas etc:
namespace RPG.UI
{
public class DamageTextCanvasSpawner : MonoBehaviour
{
[SerializeField] GameObject _damageTextCanvas;
Health _health;
private void Awake()
{
_health = GetComponentInParent<Health>();
}
private void OnEnable()
{
_health.OnTakeDamage += SpawnDamageText;
}
//Spawns the damage text canvas and sets the damage text value to the damage received.
private void SpawnDamageText(float damage)
{
GameObject damageText = Instantiate(_damageTextCanvas, transform);
damageText.GetComponentInChildren<DamageText>().SetDamageText(damage);
}
private void OnDisable()
{
_health.OnTakeDamage -= SpawnDamageText;
}
}
}
Then on the text component add the following:
namespace RPG.UI
{
public class DamageText : MonoBehaviour
{
public void SetDamageText(float damageReceived)
{
GetComponent<TextMeshProUGUI>().text = damageReceived.ToString();
}
}
}
I’m using Text mesh pro change the component to an ordinary Text if thats’ what you’re using.
This event can also be used to update the player’s health display without having to be called every update which is better for performance, In the players healthdisplay class (whatever you’ve called it) add:
private void UpdateHealthDisplay(float damageReceived)
{
string healthPercentage = String.Format("{0:0}/{1:0}", _playerHealth.CurrentHealthPoints,
_playerHealth.GetMaxHealthPoints());
_playerHealthText.text = healthPercentage;
}
Please note my code displays the current health and max health rather than the percentage, also I think my variable names are different, they basically are just accessing the players current and max health.
Remember to always subscribe and unsubscribe onEnable and OnDisable with events:
private void OnEnable()
{
_playerHealth.OnTakeDamage += UpdateHealthDisplay;
}
private void OnDisable()
{
_playerHealth.OnTakeDamage -= UpdateHealthDisplay;
}
The same can be used for enemy health display but it’s a bit more complicated.