C# Actions

So, you’ve probably done this at-least once as a developer, you’ve got a value or element of your game that needs regularly checking and updating, like; player health, score or if a level has ended. Now you can just check for these in update which in small games is fine, but you’ll find you are calling this code way more than you really need to, if only there was a way to eliminate that xD.

Introducing Actions

This is where actions come into play. They work like events such as the OnClick on a Unity UI button. When you invoke them they run, otherwise to stay as disabled. What makes them handy, like how you can have multiple methods run at once of a button is that you can add and remove methods or delegations on the fly as well as listen for actions being invoked from other scripts. Here’s the four main steps to using actions in you code:

  • Initialise the action, you can pass varied parameters into the action to pass through information you may need to use in the actions subscribers.
// Its recommended to make the action null be default, 
// as you can check for this when you call the action. 
public Action<float, float> OnHealthChange = null;
  • Subscribe our method or delegate our code to run at this point. Methods are easier to manage and are generally recommended, but if you just need to do a quick value change a delegate will work too. Its normally best to do this when the action has no parameters though. It is important to note that your method or delegation must have the same parameters defined in the initialisation.
// Subscribing to the action 
OnHealthChange += UpdateHealthBar;

// The method setup, note the parameters are the same as the action init
private void UpdateHealthBar(float health, float maxHealth)
  • Invoke the action, doing this will call all the methods subscribed to the action.
// Invoking the action... (NOTE: that we call with a null check ("?.") 
// So it doesn't invoke if nothing is subscribed to it. 
OnHealthChange?.Invoke();
  • Un-Subscribe from the action to avoid null exception errors. Recommended to run this on OnDisable or similar to avoid errors.
// Un-subscribes from the action 
OnHealthChange -= UpdateHealthBar;

Usage Example

Here’s an example which is what I used to learn how to use actions.

Health.cs (on a player)

using System;
using UnityEngine;

public class Health : MonoBehaviuor
{
	[SerialzeField] private float maxHealth = 10f;
	private float currentHealth = 10f;

	// init actions
	public Action <float, float> OnHealthChange = null;
	public Action OnNoHealth = null;

	
	public void TakeDamage(float dmg)
	{
		currentHealth -= dmg;
		// Invoking action....
		OnHealthChange?.Invoke(currentHealth, maxHealth);

		if (currentHealth <= 0)
			OnNoHealth?.Invoke();
	}
}

Healthbar.cs (on the health bar UI for the player)

using System;
using UnityEngine;

public class HealthBar : Monobehaviour
{
	[SerialzeField] private Image hpImage;
	
	private Health health;

	private void OnDisable()
	{
		// Un-subscribing from action...
		health.OnHealthChange -= UpdateHPBar;
	}

	private void Start()
	{
		// subscribing to action
		health.OnHealthChange += UpdateHPBar;
		hpSlider = GetComponent<Slider>();
	}

	// Method that has subscribed to the OnHealthChange method
       // Note: It has the same parameters!
	private void UpdateHPBar(float currentHealth, float maxHealth)
	{
		hpSlider.fillAmount = currentHealth / maxHealth;
	}
}