Object reference not set to an instance of an object

This doesnt apply to any one of the lecturers in particular. Just trying to take what I’ve learned and apply it to a new project.
The following code is attached to a shredder, like in the block breaker game. When either a player object, or an enemy object hits the shredder, its supposed to call the specified function in the specified objects script.

void OnTriggerEnter2D(Collider2D objtyp){
	if (objtyp.gameObject.CompareTag ("Player")) {
		objtyp.GetComponent<PlayerController>().killplayer();
	}
	if (objtyp.gameObject.CompareTag ("Enemy")) {
		Debug.Log("Enemy Detected");
		objtyp.GetComponent<EnemySpawner>().generateEnemy();
		Destroy(objtyp.gameObject);

	}
}

Now, when my player character goes through the shredder, killplayer() is successfully called. My player looses a life, and is started back at the beginning.

The problem is when an enemy falls through it.
When that happens, “Enemy Detected” is written to the log, and the enemy object is destroyed, but no new enemy is created.
Why wouldn’t generateEnemy() be called killplayer() is?

I’ve double checked script and function names.

It may be destroying the object before allowing it to call the method, add a timer to the destroy like: Destroy (objtyp.gameObject,0.1f), and try it again to see if this is the problem

I commented out the destroy line, and its still not working.

When the enemy falls into the shredder, the error in my title
"Object reference not set to an instance of an object" appears in the Console.

I’ve checked over my code again, and still see no reason why it shouldn’t work.

have you tried to set a timer to the destroy method?

Yeah, and then I took it out completely, just to make sure.

Chris, I`ve no clue how to fix this then… =/ I wish I could help more.

Perhaps a workaround would be to move the generateEnemy() method to this very script instead of the script inside the enemy gameObject, but I don’t know if this would be the best way to do it.

If the generateEnemy() uses the position of the enemy as input, you could also add a Vector3 variable as input to the generateEnemy() method inside the shredder, and then set this variable to the objtyp position when the collision occurs. I don’t know if this would work though.

Assuming both PlayerController and EnemySpawner are both script components, can you pop up the code for both killplayer() and generateEnemy() methods @chris.claus42, and also the class definition at the top of both scripts please.

Initial thoughts run along the lines of;

Object reference not set to an instance of an object signifies that the object doesn’t exist/hasn’t been instantiated, so we need to identify exactly which object we are talking about.

The assumption is the EnemySpawner object based on your objtyp.Getcomponent<EnemySpawner>().generateEnemy() line of code which follows the Debug.Log("Enemy Detected"); which displays to the console, and your text advising that this occurs when an enemy object hits the shredder.

Has the EnemySpawner component been added to the object?

Also, and without seeing all of the code it’s a little hard to tell, but, it may make more sense that an individual enemy wasn’t responsible for spawning another enemy. For example, you could have a Static EnemyController script and make the generateEnemy method Static also, it could be called without initialising the EnemyController, which looks to be the issue, from anywhere in your code then.

You may already be doing something along these lines so please excuse if so, again tricky to see without all the code. :slight_smile:

Slightly off topic, but assuming you only have the two types Enemy and Player to deal with at the moment, you may also want to consider adding an else in between the two if statements, this presumes a player can’t also be an enemy and vice versa.

1 Like

I’m not home so I can’t post the exact code right now, but I can answer some of your questions.

EnemySpawner is attached to an empty game object on the right side of the screen.
generateEnemy is a function in EnemySpawner.

I know that generateEnemy works, because in the start function for EnemySpawner is a call to it, which calls the first enemy.

killplayer is in PlayerController which is attached to the player prefab.

There is a third script, EnemyController, attached to the Enemy prefab, but all it does is tell the enemy to move, its not involved in the spawning or destroying of enemies right now.

When I get home, I’ll post the code for all the files.

Thanks for your help!

2 Likes

ohh, EnemySpawner isn`t attached to the enemy?

if that’s the case, then it won’t find it with objtyp.GetComponent<EnemySpawner>().generateEnemy(); since objtyp is the enemy GameObject, you should use `GameObject.Find(“Name of the object with EnemySpawner”).GetComponent().generateEnemy();``

1 Like

I concur with @Joao_Dalvi.

1 Like

**** ,you’re right.
I don’t know why that didn’t occur to me.

I set it up that way on purpose to have a static location enemies would spawn from. For some reason, I thought if the player part worked, copying and pasting it and changing the names to enemy would work too.

Thanks guys.

2 Likes

oh,

You are welcome Chris! I’m glad it was solved.
Yesterday I was developing a method to my Archer World game and I’ve gotten a couple of bugs and wrong behaviors because of copying and pasting without assuming that it could work very differently on a slightly different situation :sweat_smile:

It happens oftenly when I develop my game until late of night :joy:

1 Like

Thank you both for your help.

I’m home now, and found I only needed to modify one command.

In my shredder script, I had to change the function call to this:

objtyp.GetComponentInParent<EnemySpawner>().generateEnemy();

and it works perfectly. Every time the enemy falls off the screen, a new one is spawned.

2 Likes

Glad you got it all sorted Chris :slight_smile:

1 Like