I am trying to componentize all of my scripts and I would like the enemy to lose 1 health (enemy max health is 3) every time the player collides with the enemy. Right now the enemy is losing 2 health instead of 1. This is my hierarchy for the enemy:
There is Health and Take Damage On Collision scripts under the Enemy gameObject and a Health Bar script under the Health Bar gameObject.
Perhaps there's code running one in two separate places? I know OnCollisionEnter2D runs every frame but that's why I created a damageInterval. Here are my scripts:
public class Health : MonoBehaviour {
public int maxHealth;
public int currentHealth;
void Start() {
currentHealth = maxHealth;
}
}
public class HealthBar : MonoBehaviour {
[SerializeField] private GameObject character;
public Slider slider;
public Gradient gradient;
public Image fill;
private void Start() {
Health health = character.GetComponent<Health>();
HealthBar healthBar = gameObject.GetComponent<HealthBar>();
healthBar.SetMaxHealth(health.maxHealth);
}
public void SetMaxHealth(int health) {
slider.maxValue = health;
slider.value = health;
/*on the gradient that has (left to right) red, yellow and green fixed portions,
all the way to the left 0f (red), and all the way to the right 1f (green)
we assign the entire fill of the HealthBar to this color
*/
fill.color = gradient.Evaluate(1f);
}
public void SetHealth(int health) {
slider.value = health;
/*we assign the entire fill of the HealthBar to the normalized value (0 to 1) so
//the 0 to 10 points of health syncs with 0 to 1 on the gradient. this determines
what color the fill will be depending on how much health is left
*/
fill.color = gradient.Evaluate(slider.normalizedValue);
}
}
public class TakeDamage : MonoBehaviour {
private float damageInterval = 2f;
private float currentDamageInterval;
private void Update() {
if(currentDamageInterval >= 0)
currentDamageInterval -= Time.deltaTime;
}
public bool CanTakeDamage() {
return (currentDamageInterval < 0);
}
public void EnemyTakeDamage(int damageAmount) {
Health health = gameObject.GetComponent<Health>();
if(gameObject.CompareTag("Hazard") && CanTakeDamage()) {
health.currentHealth -= damageAmount;
currentDamageInterval = damageInterval;
if (health.currentHealth <= 0)
Destroy(gameObject);
}
}
}
public class TakeDamageOnCollision : MonoBehaviour {
[SerializeField] private int damageAmount;
[SerializeField] private GameObject healthBarGO;
HealthBar healthBar;
TakeDamage takeDamage;
private void Start() {
takeDamage = gameObject.AddComponent<TakeDamage>();
healthBar = healthBarGO.GetComponent<HealthBar>();
}
//if the player collides with enemy weak spot and can damage enemy
private void OnCollisionEnter2D(Collision2D collision) {
if (gameObject.CompareTag("Hazard") && collision.gameObject.CompareTag("Player")) {
takeDamage.EnemyTakeDamage(damageAmount);
healthBar.SetHealth(damageAmount);
}
}
}
If you have any tips on componentizing my scripts, I'm all ears.
healthBar.SetHealth(damageAmount);
this looks wrong. It sets the health to1
regardless of what happens. \$\endgroup\$