Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

NullReferenceException with Foreach?

Discussion in 'Scripting' started by VirusPunk, Jan 3, 2016.

  1. VirusPunk

    VirusPunk

    Joined:
    Aug 21, 2015
    Posts:
    25
    I wrote a hit script for shooting multiple enemies with the tag "enemy", but it is not working. I am getting:

    My HitScript code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class HitScript : MonoBehaviour
    5. {
    6.     public float hitDamage;
    7.     public bool targetIsHit = false;
    8.     private bool hasplayed = false;
    9.     public GameObject[] enemies;
    10.  
    11.     void Awake()
    12.     {
    13.         enemies = GameObject.FindGameObjectsWithTag("Enemy");
    14.     }
    15.  
    16.     void OnCollisionStay(Collision other)
    17.     {
    18.         if (other.gameObject.tag == "HitDetectBox" &&
    19.             GameObject.FindWithTag("Player").GetComponent<PlayerControl>().isFiring ||
    20.             other.gameObject.tag == "HitDetectBox" &&
    21.             GameObject.FindWithTag("Player").GetComponent<PlayerControl>().isFiringDown ||
    22.             other.gameObject.tag == "HitDetectBox" &&
    23.             GameObject.FindWithTag("Player").GetComponent<PlayerControl>().isFiringUp)
    24.         {
    25.             Invoke("HitTimer", 0.1f);
    26.         }
    27.     }
    28.  
    29.     void OnCollisionExit(Collision other)
    30.     {
    31.         if (other.gameObject.tag == "HitDetectBox")
    32.         {
    33.             targetIsHit = false;
    34.         }
    35.     }
    36.  
    37.     void HitTimer()
    38.     {
    39.         targetIsHit = true;
    40.         foreach (GameObject Enemy in enemies)
    41.         {
    42.             GetComponent<DummyAI>().curHP -= hitDamage;
    43.             Debug.Log("Enemy HP currently at: " + GetComponent<DummyAI>().curHP);
    44.         }
    45.     }
    46. }
    As you can see, I tried to manually assign each enemy on my scene in the inspector, but same result. DummyAI is obviously assigned to each enemy as they do what I programmed them to do. So I can't understand where this null exception is coming from?
     
  2. VirusPunk

    VirusPunk

    Joined:
    Aug 21, 2015
    Posts:
    25
    OK, so I changed this to this:

    Code (CSharp):
    1.     void HitTimer()
    2.     {
    3.         targetIsHit = true;
    4.         foreach (GameObject Enemy in enemies)
    5.         {
    6.             Enemy.GetComponent<DummyAI>().curHP -= hitDamage;
    7.             Debug.Log("Enemy HP currently at: " + Enemy.GetComponent<DummyAI>().curHP);
    8.         }
    9.     }
    But instead of just killing the enemy I'm targeting it deals damage to all enemies at the same time...
     
  3. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,021
    You are literally telling it to do "hitDamage" to each "Enemy".
     
  4. VirusPunk

    VirusPunk

    Joined:
    Aug 21, 2015
    Posts:
    25
    Thanks, but when I remove the foreach loop and make it a single object, it can only destroy one and returns a null reference exception for the rest of the enemies in the scene..
     
  5. VirusPunk

    VirusPunk

    Joined:
    Aug 21, 2015
    Posts:
    25
    Solved it. Turns out the game couldn't find any more objects in the "Enemy" tag as it was only specified in the Start or Awake method. So once one object was destroyed, it couldn't find the others. Telling the Hit invoke to look for "enemy" again is what did the trick here.

    Code (CSharp):
    1.     void HitTimer()
    2.     {
    3.         targetIsHit = true;
    4.         if (enemy != null)
    5.         {
    6.             enemy.GetComponent<DummyAI>().curHP -= hitDamage;
    7.             Debug.Log("Enemy health at: " + enemy.GetComponent<DummyAI>().curHP);
    8.         }
    9.         enemy = GameObject.FindGameObjectWithTag("Enemy");
    10.     }