C# Referencing a Non-Static Variable Help

ok so me and a few friends have started working on this game and i was put in charge of programming. anyway i was working on a way to add multiple enemies into a scene, and needed to get rid of the static variable that i was currently using as a place holder. now when i shoot an enemy i get a null reference pointer error. please help :slight_smile:

GunScript Code

using UnityEngine;
using System.Collections;

public class GunScript : MonoBehaviour {
	
	/**
	 * Next Objective is making a list to organize the guns and make this script the only script for guns.
	 * */
	
	//How much damage the gun does.
	public int dmg;
	//How long the muzzle flash lasts.
	public float delay;
	//Stores if the raycast hit an object.
	RaycastHit hit;
	//How fast the bullet travels (Not implemented yet).
	public float bulletSpeed;
	//How much ammo the clip can hold.
	public int clipSize;
	//Used to display where the ammo counter is located.
	public float pixDown;
	public float pixRight;
	//How much Ammunition is currently in the gun.
	public int Ammo;
	//Used to display the particle system of the muzzle flash (will be switching to a 2D texture soon).
	public ParticleSystem muzzelFlash;
	//Holds the light that appears when a gun is shot.
	public Light muzzelLight;
	//Stores the audio clip of the gun shot.
	public AudioClip shot;
	//Stores the audio clip of the reloading sound.
	public AudioClip reloadSound;
	//How long the muzzle flash lasts.
	float flashTime = 0.05f;
	//How long the gun takes to reload.
	public float reloadTime;
	//Used to style the gui of the ammo counter.
	public GUIStyle text = new GUIStyle();
	//Checks to see if the gun is reloading.
	bool isReloading;
	//Used to call Enemy Health from the EnemyAI script.
	public EnemyAI enemy;
	
	// Use this for initialization
	void Start () {
		//Makes sure that the muzzle flash is off.
		muzzelFlash.renderer.enabled = false;
		muzzelLight.enabled = false;
		//Gets the enemy ai script.
		enemy = GetComponent<EnemyAI>();
	}
	
	// Update is called once per frame
	void Update () {
		//Fires When Mouse1 is pressed.
		if(Input.GetButtonDown("Fire1") && Ammo > 0 && isReloading == false)
		{
			//Plays the shot sound when fired.
			audio.PlayOneShot(shot);
			//Subtracts one from the ammo counter.
			Ammo = Ammo - 1;
			StartCoroutine(Shoot());
			
			//Not working :(
			if(Input.GetKeyDown("r")){
				Debug.Log("Button Pressed");
				StartCoroutine(Reload());
			}
		}
	}
	
	//Displays ammo in clip
	void OnGUI(){
		//Displays the current ammo in the gun clip.
		GUI.Label(new Rect(Screen.width * pixRight, Screen.height * pixDown, 100, 20), "" + Ammo, text);
	}
	
	//Fires Gun Off
	IEnumerator Shoot()
	{
		//Enables muzzel flash.
		muzzelFlash.renderer.enabled = true;
		muzzelLight.enabled = true;
	
		//Enables the raycast.
		if(Physics.Raycast(transform.position, transform.forward, out hit, 100)){
			//Draws a line in the scene view to see where the bullet hit, if it hit.
			Debug.DrawLine(transform.position, hit.point, Color.green, 0.3f);
			//Checks to see if the raycast hit an Enemy. If so than do damage to the enemy.
			if(hit.collider.gameObject.tag == "Enemy"){
			enemy.health -= dmg;
			}
		}
		//Waits for however long the flashTime is.
		yield return new WaitForSeconds(flashTime);
		//Disables muzzle flash.
		muzzelFlash.renderer.enabled = false;
		muzzelLight.enabled = false;
		
		//Checks to see if the gun is out of ammo. If so then run the Reload function.
		if(Ammo == 0)
			StartCoroutine(Reload());
	}
	
	//Reloading function (will add animation eventually).
	public IEnumerator Reload()
	{
		//Changes the boolean "isReloading" to true to symbolize that the gun is reloading.
		isReloading = true;
		//Plays the reloading sound.
		audio.PlayOneShot(reloadSound);
		//Waits for the reload time to be complete.
		yield return new WaitForSeconds(reloadTime);
		//Changes the ammo to full
		Ammo = clipSize;
		//Changes the boolean "isReloading" to false to symbolize that the gun is not reloading.
		isReloading = false;
	}
	
}

And the EnemyAI Script

using UnityEngine;
using System.Collections;

public class EnemyAI : MonoBehaviour {
	
	//The distance at which AI can attack the player.
	public int startAttack;
	//Determines if the player is under attack.
	bool attack;
	//How long between the AI's attacks
	public int attackTimer;
	//Distance at which the AI will start.
	public int startAttackDistance;
	//Who the AI will attack.
	public Transform target;
	//Move speed of the AI.
	public float moveSpeed;
	//Rotation speed of the AI.
	public float rotationSpeed;
	//Used to find the cube's position.
	public Transform myTransform;
	//Cubes Health.
	public float health = 10;
	
	
	void Awake(){
		//Targets Player once level is started.
		target = GameObject.FindGameObjectWithTag("Player").transform;
	}
	// Use this for initialization
	void Start () {
		//Used to find the AI's position.
		myTransform = transform;
	}
	
	// Update is called once per frame
	void Update () {
				
		//Used to determine if the player is close enough to the AI to engage an attack.
		float distance = (target.position - myTransform.position).magnitude;
		
		//Starts the AI attack.
		if(distance < startAttackDistance){
			
			//Draws a line in the scene to show what the AI is targeting.
			Debug.DrawLine(myTransform.position, target.position, Color.cyan);
		//Rotates towards the player.
		myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed * Time.deltaTime);
		
		//Moves toward the player.
		myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
						
			if(distance <= startAttack && attack == false)
				StartCoroutine(Attack());
		}
		//Checks to see the health of the AI. If it is 0, then destroy the AI.
		if(health <= 0)
			Destroy(gameObject);
		if(health < 0)
			health = 0;
	}
	
	IEnumerator Attack(){
		attack = true;
		yield return new WaitForSeconds(attackTimer);
		PlayerHealth.playerHealth -=1;
		attack = false;
	}
	
	public void Damage(){
		health -= 1;
	}	
}

You are showing me a lot of code and then telling me that something is null. What line does it return that error on? Maybe post just that snippet.

Without much context however, you can check if something is null before using it.

For example if you are defining a component like so:

enemy = transform.GetComponent<EnemyAI>();

What if you forget to attach that script on the object? It would fail to find it and becomes null, returning an error when you try to do something with it maybe…here:

enemy.health -= dmg; //You could get a null reference

The safe way is to do check first:

if(enemy != null)
     //Do stuff

This of course depends on what you’re doing. But finding gameobjects and getting components is the most likely way to get a null reference because its fairly unsafe by nature.

You should get the EnemyAI script of the hit object, like this:

     ...
     if(hit.collider.tag == "Enemy"){
         // get the EnemyAI script of the hit object:
         enemy = hit.collider.GetComponent< EnemyAI>();
         // if script found, apply the damage:
         if (enemy) enemy.health -= dmg;
     }
     ...