NullReferenceExeption but everything works great...

Hi, this is my first question so I think I have to introduce myself (you can skip this part from here…):
I’m Pascal, I’m new in coding and Unity world (and if you found grammar errors or if I’m using a word for another, my apologies, I do my best to avoid that but I’m French, yep no one is perfect).
(… To here)

So, my main Camera has an Animator component with 3 animations:

  • A new State (I use it as a hub).
  • “startGame” animation (triggered when a new game start).
  • “screenShake” animation triggered at some events.

And I have 2 parameters:

  • Bool screenshake.
  • Bool startGame.

And my main Camera has a script CameraScript attached to it.

using UnityEngine;
using System.Collections;

public class CameraScript : MonoBehaviour 
{
 	public static Animator animator;
	public static int screenShakeHash = Animator.StringToHash("screenShake");
	public static int startGameAnimHash = Animator.StringToHash("startGame");

	public static WaitForEndOfFrame wait = new WaitForEndOfFrame();

	void Awake()
	{
		animator = GetComponent<Animator>();
	}

	public static void Shake(bool enable)
	{
		animator.SetBool(screenShakeHash, enable);
	}

	public static IEnumerator ShakeOnce()
	{
		Shake(true);

		yield return wait;

		Shake(false);
	}

	public static void StartGameAnim(bool enable)
	{
		animator.SetBool(startGameAnimHash, enable);
	}
}

And I have 3 “NullReferenceException: Object reference not set to an instance of an object”…

That did’nt appeared the first time I launched my game.

More info:
NullReferenceException: Object reference not set to an instance of an object
CameraScript.Shake (Boolean enable) (at Assets/Scripts/CameraScript.cs:19)
LaserGameFieldClamper+c__Iterator10.MoveNext () (at Assets/Scripts/LaserGameFieldClamper.cs:72)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
LaserGameFieldClamper:OnEnable() (at Assets/Scripts/LaserGameFieldClamper.cs:56)
UnityEngine.Object:Instantiate(Object, Vector3, Quaternion)
GameManager:ObjectSpawner(GameObject, GameObject) (at Assets/Scripts/GameManager.cs:340)
GameManager:Awake() (at Assets/Scripts/GameManager.cs:73)

And everything works fine…
When my game start “startGame” animation is triggered, the two functions, StartGameAnim() and Shake(), do what they have to do and the Coroutine too…

Please Unity comunity, teach me!

This line:

animator = GetComponent<Animator>();

Does not ENSURE that animator is given a valid (non-null) value. This is because if the object does not contain an Animator component, this function is SUPPOSED to return null.

So, it is imperative that you confirm the value of animator is NOT null, before you use it.
e.g.

public static void Shake(bool enable)
     {
         if(animator!=null)
             animator.SetBool(screenShakeHash, enable);  //the animator and DOT, means we are "using" the variable
         if(animator==null)
               Debug.Log("somethig is wrong, there is no animator attached!");
     }

I see that you check the value in your comments, and reassign it, if null. This is a good idea, but again, for the same reason as above, this does not ENSURE the value is not null.