If one prefab enemy dies, the other enemy prefabs malfunction
MissingReferenceException: The object of type 'EnemyHealth' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. EnemyHealth.Die () (at Assets/Scripts/Enemy/EnemyHealth.cs:33) EnemyHealth.TakeDamage (System.Int32 damage) (at Assets/Scripts/Enemy/EnemyHealth.cs:26) PlayerCombat.Attack () (at Assets/PlayerCombat.cs:53) PlayerCombat.Update () (at Assets/PlayerCombat.cs:37)
So when I attack a prefab enemy and one of those prefab reach a health of 0 and destroys their game, the other enemies' health script from the prefab malfunctions, even though they didn't get destroyed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyHealth : MonoBehaviour
{
public int enemy_maxHealth = 100;
int enemy_currentHealth;
public Enemy_Healthbar enemy_HB;
void Start()
{
enemy_currentHealth = enemy_maxHealth;
enemy_HB.EnemySetMaxHealth(enemy_maxHealth);
}
public void TakeDamage(int damage)
{
enemy_currentHealth -= damage;
enemy_HB.EnemySetHealth(enemy_currentHealth);
if(enemy_currentHealth <= 0)
{
Die();
}
}
void Die()
{
Debug.Log("this mf dead");
Destroy(gameObject);
}
}
This is for the Enemy AI, which instructs the enemy to attack the player and deal damage to the player, might be helpful if I put it in here as well.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
#region Public Variables
public Transform rayCast;
public LayerMask raycastMask;
public float rayCastLength;
public float attackDistance; //Minimum distance
public float moveSpeed;
public float timer; //Cooldown of attacks
public Transform leftLimit;
public Transform rightLimit;
public int AttackDamage;
public Transform triggerArea;
public LayerMask Player;
#endregion
#region Private Variables
private RaycastHit2D hit;
private Transform target;
private Animator animator;
private float distance; //store distance between enemy and player
private bool attackMode;
private bool inRange; //See if player in range
private bool cooling; //check if enemy is cooling after attack
private float intTimer;
private PlayerHealth playerHS;
#endregion
void Awake()
{
SelectTarget();
intTimer = timer;
animator = GetComponent<Animator>();
playerHS = GetComponent<PlayerHealth>();
}
// Update is called once per frame
void Update()
{
if (!attackMode)
{
Move();
}
if (!InsideofLimits() && !inRange && !animator.GetCurrentAnimatorStateInfo(0).IsName("enemy1Attack"))
{
SelectTarget();
}
if (inRange)
{
hit = Physics2D.Raycast(rayCast.position, transform.right, rayCastLength, raycastMask);
RaycastDebugger();
}
//When player is detected
if (hit.collider != null)
{
EnemyLogic();
}
else if (hit.collider == null)
{
inRange = false;
}
if (inRange == false)
{
StopAttack();
}
}
void OnTriggerEnter2D(Collider2D trig)
{
if (trig.gameObject.tag == "Player")
{
target = trig.transform;
inRange = true;
Flip();
}
}
void EnemyLogic()
{
distance = Vector2.Distance(transform.position, target.position);
if (distance > attackDistance)
{
StopAttack();
}
else if (attackDistance >= distance && cooling == false)
{
Attack();
}
if (cooling)
{
Cooldown();
animator.SetBool("Attack", false);
}
}
void Move()
{
animator.SetBool("Run", true);
if (!animator.GetCurrentAnimatorStateInfo(0).IsName("enemy1Attack"))
{
Vector2 targetPosition = new Vector2(target.position.x, transform.position.y);
transform.position = Vector2.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
}
}
void Attack()
{
timer = intTimer;
attackMode = true;
animator.SetBool("Run", false);
animator.SetBool("Attack", true);
hit.collider.gameObject.GetComponent<PlayerHealth>().TakeDamage(AttackDamage);
}
void Cooldown()
{
timer -= Time.deltaTime;
if (timer <= 0 && cooling && attackMode)
{
cooling = false;
timer = intTimer;
}
}
void StopAttack()
{
cooling = false;
attackMode = false;
animator.SetBool("Attack", false);
}
void RaycastDebugger()
{
if (distance > attackDistance)
{
Debug.DrawRay(rayCast.position, transform.right * rayCastLength, Color.red);
}
else if (attackDistance > distance)
{
Debug.DrawRay(rayCast.position, transform.right * rayCastLength, Color.green);
}
}
public void TriggerCooling()
{
cooling = true;
}
private bool InsideofLimits()
{
return transform.position.x > leftLimit.position.x && transform.position.x < rightLimit.position.x;
}
private void SelectTarget()
{
float distanceToLeft = Vector2.Distance(transform.position, leftLimit.position);
float distanceToRight = Vector2.Distance(transform.position, rightLimit.position);
if (distanceToLeft > distanceToRight)
{
target = leftLimit;
}
else
{
target = rightLimit;
}
}
private void Flip()
{
Vector3 rotation = transform.eulerAngles;
if (transform.position.x > target.position.x)
{
rotation.y = 180f;
}
else
{
rotation.y = 0f;
}
transform.eulerAngles = rotation;
}
}