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.