More modular approach to health and damage

Hi

My approach was to have a more modular approach.
So instead of baking in the health actions and damage actions on the projectile, I made a script for Damage, and Health and added this as components to my attacker.

I also used collisions instead of triggers, I tend to think of a collision been between physical entities, and a trigger as something invisible, such as when you might want to trigger a cutscene when the player walks to a certain area.

So in my attacker I detect for the collision (this particular attacker doesn’t have a projectile), and if the collision is with “friendly” (could have made this defender so it was more obvious) and the “friendly” has a health component it will ApplyDamage

public void OnCollisionEnter2D(Collision2D collision)
    {
        GameObject gameObject = collision.gameObject;
        if (gameObject.tag == "Friendly")
        {
            Health collisionHealth = gameObject.GetComponent<Health>();
            if (collisionHealth != null)
            {
                damage.ApplyDamage(health, attackPower);
            }
        }
        
    }

For completeness sake here’s the full scripts for the Attacker, Damage and Health:

public class Attacker : MonoBehaviour
{
    [Range (0f, 5f)]
    float currentSpeed = 1f;

    [SerializeField] int attackPower = 100;

    private Health health;
    private Damage damage;

    void Start()
    {
        damage = GetComponent<Damage>();
        health = GetComponent<Health>();
    }

    void Update()
    {
        transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
    }

    public void SetMovementSpeed(float speed)
    {
        currentSpeed = speed;
    }

    public void OnCollisionEnter2D(Collision2D collision)
    {
        GameObject gameObject = collision.gameObject;
        if (gameObject.tag == "Friendly")
        {
            Health collisionHealth = gameObject.GetComponent<Health>();
            if (collisionHealth != null)
            {
                damage.ApplyDamage(health, attackPower);
            }
        }
        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Damage : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    }

    public void ApplyDamage(Health health, int damage)
    {
        Debug.Log("Apply damage: " + damage.ToString());
        health.DecreaseHealth(damage);
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Health : MonoBehaviour
{
    [SerializeField] int health = 100;

    public int GetHealth()
    {
        return health;
    }

    public void DecreaseHealth(int amount)
    {
        health -= amount;
    }

    public void IncreaseHealth(int amount)
    {
        health += amount;
    }

    void Update()
    {
        if (health <= 0)
        {
            Debug.Log("Health of " + gameObject.name + " = " + health.ToString());
            Destroy(gameObject);
        }
    }
}

It might seem like over-engineering for this project, but now I can easily add Health to other prefabs and also allow them to “ApplyDamage” to other prefabs.

Thanks for sharing @Jamie_Sandell!
I know nothing I haven’t learned in this course, so take this with a pinch of salt, but i tend to agree with you. It feels like good practice at teasing out what each object does.

1 Like

Privacy & Terms