I have a relatively simple game in Unity3D that has some zombies moving towards a central base and attacking it until it's health reaches 0. The attacks are run in a co-routing to create a delay between them. The problem is have here is that once you kill an enemy the co-routine keeps on running. I've assigned a bool isAttacking to the Enemy script which is initialized to false, set to true when the enemy is attacking and set back to false again when the enemy is dead. The coroutine that controls the attacks shouldn't run if isAttacking is set to false but for some reason it still carries on running even if the enemy is dead. Whats really confusing me is that if I run the game, wait for the coroutine to start, kill the enemy and then manually untick 'isAttacking' in the inspector then the co-routine stops running. I've included both the Enemy & Base scripts, any help is appreciated.
BASE SCRIPT
using UnityEngine;
using System.Collections;
public class Base : MonoBehaviour {
public float Health = 100f;
public float AttackSpeed = 2f;
//VOID AWAKE - START . contains getcomponent code
public Enemy enemy;
void awake(){
enemy = GetComponent<Enemy>();
}
//VOID AWAKE - END
//If enemy touches the base
void OnCollisionEnter2D(Collision2D col){
Debug.Log ("Base touched");
if(col.gameObject.tag == "Enemy"){
enemy.isAttacking = true;
if(Health > 0f){
Debug.Log ("Enemy attacking base");
StartCoroutine("enemyAttack");
}else{
enemy.isAttacking = false;
}
}
}
//Coroutine that deals damage
public IEnumerator enemyAttack(){
while(Health > 0f){
if(enemy.isAttacking == true){
yield return new WaitForSeconds(2f);
Health -= Enemy.Damage;
Debug.Log ("Base health at: " + Health);
}else{
yield break;
}
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Load Lose Screen when Base health reaches 0
if (Health <= 0){
Application.LoadLevel("Lose Screen");
}
}
}
ENEMY SCRIPT
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public static float Damage = 10.0f;
public float Health = 20.0f;
public Transform target;
public float Speed;
public bool isAttacking = false;
//If the player collides with the enemy
void OnTriggerEnter2D(Collider2D col)
{
if(col.gameObject.tag == "Player")
{
Debug.Log("Player hits enemy");
Health -= PlayerController.Damage;
Debug.Log("Enemy health at: " + Health);
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Destroy the enemy if it's health reaches 0
if(Health <= 0){
isAttacking = false;
Debug.Log ("Is attacking: " + isAttacking);
Destroy(this.gameObject);
Debug.Log ("Enemy Destroyed!");
}
//Constantly move the enemy towards the centre of the gamespace (where the base is)
float step = Speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
EDIT Currently the problem is solved except for the fact that if the player touches the base then all enemies stop attacking. I've updated the code to show it in its current state. BASE SCRIPT using UnityEngine; using System.Collections;
public class Base : MonoBehaviour {
public float Health = 100f;
public float AttackSpeed = 2f;
//VOID AWAKE - START . contains getcomponent code
public Enemy enemy;
void awake(){
enemy = GetComponent<Enemy>();
}
//VOID AWAKE - END
//If enemy touches the base
void OnCollisionEnter2D(Collision2D col){
Debug.Log ("Base touched");
if(col.gameObject.tag == "Enemy" && Health > 0f){
enemy.isAttacking = true;
Debug.Log ("Enemy attacking base");
StartCoroutine("enemyAttack");
}
else{
enemy.isAttacking = false;
}
}
//Coroutine that deals damage
public IEnumerator enemyAttack(){
while(Health > 0f){
if(enemy.isAttacking == true){
yield return new WaitForSeconds(2f);
Health -= Enemy.Damage;
Debug.Log ("Base health at: " + Health);
}else{
yield break;
}
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Load Lose Screen when Base health reaches 0
if (Health <= 0){
Application.LoadLevel("Lose Screen");
}
}
}
ENEMY SCRIPT
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public static float Damage = 10.0f;
public float Health = 20.0f;
public Transform target;
public float Speed;
public bool isAttacking = false;
//If the player collides with the enemy
void OnTriggerEnter2D(Collider2D col)
{
if(col.gameObject.tag == "Player")
{
Debug.Log("Player hits enemy");
Health -= PlayerController.Damage;
Debug.Log("Enemy health at: " + Health);
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Destroy the enemy if it's health reaches 0
if(Health <= 0){
isAttacking = false;
Debug.Log ("Is attacking: " + isAttacking);
Destroy(this.gameObject);
Debug.Log ("Enemy Destroyed!");
}
//Constantly move the enemy towards the centre of the gamespace (where the base is)
float step = Speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}