NullReferenceException: Object reference not set to an instance of an object

Hi, I am pretty new to C# and unity at the start, plus I am doing this out of my interest, so my question could be basic. However it has bugged me for so long, that I couldn’t get it over even after I research it over the internet.

Anyway, here is my question, I have got this error NullReferenceException: Object reference not set to an instance of an object two times over my script.

The first time is when I wanted to set the respawn action only execute after the player enters the “Dying state”, I have use Debug.Log to ensure it successfully enters the Dying state, but when I click the respawn button after the player dies, the error pops up.

The second error happens whenever I press the attack button, which I intend to let my player throw grenade or whatever.

**Codes as bellow **

My PlayerController script, and it works fine

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(PlayerPhysics))]
public class PlayerController : Entity {

// Player Handling
public float gravity = 20;
public float speed = 8;
public float acceleration = 30;
public float jumpHeight = 16;
public float slideDeceleration = 1;


// System
private float animationSpeed;
private float currentSpeed;
private float targetSpeed;
private Vector2 amountToMove;
	
// States
[HideInInspector]
public bool Dying;

private bool jumping;
private bool sliding;
private bool still;
private bool falling;
private bool throwing;
private bool droping;
private bool bumping;

// Componenets
private PlayerPhysics playerPhysics;
private Animator animator;
private GameManager manager;
private PlayerAttack attack;

void Start () {
	playerPhysics = GetComponent<PlayerPhysics>();
	animator = GetComponent<Animator>();
	manager = Camera.main.GetComponent<GameManager>();
}


void Update () {
	
	if(GetComponent<Entity>().Died!=true){
	
		Dying=false;
	#region player alive movement
	// Reset acceleration upon collision
	if (playerPhysics.movementStopped) {
		targetSpeed = 0;
		currentSpeed = 0;
	}
	
	// If player is touching the ground
	if (playerPhysics.grounded) {
		amountToMove.y = 0;

		// Jump logic
		if (jumping) {
			jumping = false;
			animator.SetBool("Jumping",false);
		}
	
		// Jump
		if(!sliding){
			if (Input.GetButtonDown("Jump")) {
				amountToMove.y = jumpHeight;
				jumping = true;
				animator.SetBool("Jumping",true);
			}
		}
		
			
		// Slide Input & logic
		if (Input.GetButton("Slide")) {
			sliding = true;
			animator.SetBool("Sliding",true);
			targetSpeed = 0;
			
			playerPhysics.SetCollider(new Vector3(5,2.2f,1.79f), new Vector3(-0.17f,1.1f,-1.24f));
		
			}
		else {
				sliding = false;
				animator.SetBool("Sliding",false);
			
				playerPhysics.ResetCollider();
			}
		if(amountToMove.x==0){
			still=true;
			animator.SetBool("Still", true);
		} else {
			still=false;
			animator.SetBool("Still", false);
		}
		
	}
	
	//falling logic
	if(!playerPhysics.grounded){
		if(!jumping){
			falling=true;
			animator.SetBool("Falling", true);
		}
	}
	else { 
		falling=false;
		animator.SetBool("Falling", false);
	}
	
	// Set animator parameters
	animationSpeed = IncrementTowards(animationSpeed,Mathf.Abs(targetSpeed),acceleration);
	animator.SetFloat("Speed",animationSpeed);

	
	// Input
	if (!sliding) {
			//movement
			targetSpeed = Input.GetAxisRaw("Horizontal") * speed;
			currentSpeed = IncrementTowards(currentSpeed, targetSpeed,acceleration);
	
			// Face Direction
			float moveDir = Input.GetAxisRaw("Horizontal");
			if (moveDir !=0) {
				transform.eulerAngles = (moveDir>0)?Vector3.zero:Vector3.up * 180;
			}
		}
			else {
		currentSpeed = IncrementTowards(currentSpeed, targetSpeed,slideDeceleration);
		}
	
	// Set amount to move
	amountToMove.x = currentSpeed;
	amountToMove.y -= gravity * Time.deltaTime;
	playerPhysics.Move(amountToMove * Time.deltaTime);
	#endregion
	}else{
	#region player dead movement
		Dying=true;
		animator.SetBool("Die", true);
		targetSpeed=0;
		currentSpeed = IncrementTowards(currentSpeed, targetSpeed,slideDeceleration);
		amountToMove.x = currentSpeed;
		amountToMove.y -= gravity * Time.deltaTime;
		playerPhysics.Move(amountToMove * Time.deltaTime);
		#endregion
	}	
	
	
	//Attack
	if (Input.GetButtonDown("LRangeAttack")) {
			//attack.Throw();
		Debug.Log("throwing now");
			GetComponent<PlayerAttack>().Throw();
			//	throwing = true;
			//	animator.SetBool("Throwing",true);
			}
	
		//complete level (need to set up)
//		if(GetComponent<Enemies>().EnemiesNum==0){
//			manager.EndLevel();
//		}
	}

//probably not necessary, may change to second player
void OnTriggerEnter(Collider c) {
	if (c.tag == "Checkpoint") {
		manager.SetCheckpoint(c.transform.position);
	}
	//if (c.tag == "Finish") {
	//	manager.EndLevel();
	//}
}

// Increase n towards target by speed
private float IncrementTowards(float n, float target, float a) {
	if (n == target) {
		return n;	
	}
	else {
		float dir = Mathf.Sign(target - n); // must n be increased or decreased to get closer to target
		n += a * Time.deltaTime * dir;
		return (dir == Mathf.Sign(target-n))? n: target; // if n has now passed target then return target, otherwise return n
		}
}

}

then here is my GameManager script, where the first error pops in when I want to respawn

***NullReferenceException: Object reference not set to an instance of an object
GameManager.Update () (at Assets/Scripts/GameManager.cs:30)


which is line if(GetComponent().Dying=true) in GameManager script

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
	
	public GameObject player;
	private GameObject currentPlayer;
	private GameCamera cam;
	private Vector3 checkpoint;
	
	public static int levelCount = 100;
	public static int currentLevel = 1;
	
	void Start () {
		cam = GetComponent<GameCamera>();
		if (GameObject.FindGameObjectWithTag("Spawn")) {
			checkpoint = GameObject.FindGameObjectWithTag("Spawn").transform.position;
		}
		SpawnPlayer(checkpoint);
	}
	
	// Spawn player
	private void SpawnPlayer(Vector3 spawnPos) {
		currentPlayer = Instantiate(player,spawnPos,Quaternion.identity) as GameObject;
		cam.SetTarget(currentPlayer.transform);
	}
	
		private void Update() {
		if (Input.GetButtonDown("Respawn")) {
			if(GetComponent<PlayerController>().Dying=true)
				Destroy(currentPlayer.gameObject);
				SpawnPlayer(checkpoint);

		}
	}
	
		public void SetCheckpoint(Vector3 cp) {
		checkpoint = cp;
	}
	
		public void EndLevel() {
		if (currentLevel < levelCount) {
			currentLevel++;
			Application.LoadLevel("Level " + currentLevel);
		}
		else {
			Debug.Log("Beta ends here, more coming~");
		}
	}
	
}

and now the second errors in my PlayerAttack script, I have yet completed the function but the error still shows

NullReferenceException: Object reference not set to an instance of an object
PlayerController.Update () (at Assets/Scripts/PlayerController.cs:158)

which is line GetComponent().Throw(); in PlayerController script

using UnityEngine;
using System.Collections;

public class PlayerAttack : MonoBehaviour {

	public void Throw() {
			Debug.Log("THROW");
		}
}

Robert is completely right. You have to call Getcomponent on the GameObject that actually has the component. If these scripts are assigned to different gameobjects, the call will return null resulting in the error.

One way to resolve this is to add references to the other gameobjects in your script.

Example: To resolve the first issue, add

public GameObject playerObject;

to the GameManager. In the inspector you can drag & drop your player gameobject into this one to set it.

Then in line 30, you write

if(playerObject.GetComponent<PlayerController>().Dying==true)

(Note that for comparisons you HAVE TO use == and not = as the latter is reserved for assigning. In this case you can even omit the == true entirely as Dying is already a bool).

A thing you can also do is :
hit.collider.gameObject.GetComponent().Dying == true;

this is a better solution if you have more then one player you would like to check.
then the script also doesnt have to be on the same object
but then you need to have a raycast to look what you hit, (Raycasthit hit, its the point where the raycast hits an object and then checks whether that object has the script, PlayerController)

Just something that might come in handy later, or for other people :slight_smile: