- Home /
Composition: Multiple actions on death
Hello, Trying to understand Composition based design a little more.
I have a Health and an abstract Death Class. I inherite different child classes from the DeathClass like GameOverOnDeath, ExplodeOnDeath, DropItemOnDeath. Now i want to have an enemy to explode on death but to also drop some items on death. Whats the best approach top this?
(Other Question: Is there a good comprehensive guide to Composition based design WITH UNITY? Can't find any useful resources)
Health.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Death))]
public class Health : MonoBehaviour
{
private Death death;
[SerializeField] private int startingHealth;
private int health;
private void Awake()
{
death = GetComponent<Death>();
}
public void TakeDamage(int amount)
{
health -= amount;
if (health <= 0f)
{
Die();
}
}
public void Heal(int amount)
{
health += amount;
if (health > startingHealth)
{
health = startingHealth;
}
}
public void Die()
{
death.OnDeath();
}
}
Death.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class Death : MonoBehaviour
{
public abstract void OnDeath();
}
And as example here is one of my inherited death child classes "GameOverOnDeath"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverOnDeath : Death
{
public override void OnDeath()
{
LevelManager.Instance.GameOver();
}
}
Answer by Captain_Pineapple · Feb 13 at 03:06 PM
In general i'd say your approach is already good.
i'd do it a bit different as the Death
class does not really contain enough to legitimize its own Monobehaviour.
So basically I'd give all your current functionality to the Health
class and then you extend your class by an OnDeathCallback
like this:
public System.Action OnUnitDiedCallback;
To this you can subscribe from other classes:
GetComponent<Health>().OnUnitDiedCallback += someFunctionToTrigger;
So for example if we assume you have some GameManager
that detects the game end you could have:
playerCharacter.GetComponent<Health>().OnUnitDied += gameEnd;
and so on. The actual call to this is done like this:
public void Die()
{
OnUnitDiedCallback?.Invoke();
}
In case you don't know the ?
operator: that checks the OnUnidDiedCallback
if it is null
or not.
Hope this helps. Let me know if something was unclear.
Okay, thank you. That sounds like a good approach. But with this i am not sure how to handle the other cases. So if a unit does different thing on death ( drops an item, explodes and plays a sound) how to achieve that? Have an item drop manager for the item drop maybe? But how to play sounds and effects in a composition based system? Should the "Health.cs" have a Slot for a deathSound, a deathFX, a damageSound and a damageFX? Then it would check if those are not empty and play them? Or make another component "FXPlayer" and ''AudioPlayer" and check if those have a filled deathFx and deathSound slot?
BTW: Didn't know the ? Operator but now i know. Thank you!
You can subscribe as many functions to OnUnitDiedCallback
as you like.
OnUnitDiedCallback += centralSoundManager.PlayDeathSound;
OnUnitDiedCallback += dropManager.DropItem;
//and so on...
To have a centralized drop function would require however that you know where to drop something so your OnUnitDiedCallback Action might need a parameter so your Action might have to look like something like this:
public System.Action<Health> OnUnitDiedCallback;
So your call in your health script is then:
public void Die()
{
OnUnitDiedCallback?.Invoke(this);
}
Like that you can then on the other side access the transforms position from the given health script.
Regarding the sounds i personally would give that to my unit behaviour script. So when you have your unitbehaviour that would have some things assigned like what sound to play when it dies. So in your Awake
you can just the same subscribe to the ondeath callback of the Health
script.
Your answer
Follow this Question
Related Questions
Class inheriting Runtime Classes 1 Answer
Inheritance and Component Types in C# 2 Answers
Game architecture best practices 3 Answers
How unity works under the hood? 0 Answers