- Home /
Array or for loop doesn't work with state machine in Unity, gives NullReferenceException
The randomizeMonster function gives a NullReferenceException: Object reference not set to an instance of an object, when it's called from the state machine. randomizeMonster works if i call it from the start or update functions. I think i've tracked the problem to the AllMonsters array, but i don't know how to solve it.
Help is much appreciated :)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class BattleStateStart : MonoBehaviour {
public string region; //current region
public monster[] AllMonsters; //array for premade monsters
public monster enemyMonster; //the generated enemy
public monster monsterEquiped; //our monster
// Use this for initialization
void Start () {
Debug.Log(AllMonsters.Length);
randomizeMonster (); //<<<<<<<< Calling randomizeMonster in update or start works, from boths classes
}
// Update is called once per frame
void Update () {
}
public void PrepareBattle(){
Debug.Log ("Preparing for battle");
randomizeMonster ();
}
//The NullReferenceException: Object reference not set to an instance of an object is somehow caused by the
//AllMonsters array. If i change AllMonsters.Length bellow to ex. 3 then it works but then the problem jumps to the next
//place AllMonsters[] is used.
void randomizeMonster(){
List<monster> tempMonster = new List<monster>();
int randomNumber = Random.Range(0,100);
if(randomNumber==20){
for(int i=0;i<AllMonsters.Length;i++){
if(AllMonsters[i].rarity==monster.Rarity.Rare && AllMonsters[i].Location==region){
tempMonster.Add(AllMonsters[i]);
}
}
}else{
for(int j=0;j<AllMonsters.Length;j++){
if(AllMonsters[j].rarity==monster.Rarity.Common && AllMonsters[j].Location==region){
tempMonster.Add(AllMonsters[j]);
}
}
}
int newRandom = Random.Range (0, tempMonster.Count);
enemyMonster = tempMonster [newRandom];
}
//Basic monster GUI
void OnGUI(){
//Enemy monster
GUI.Label (new Rect (Screen.width / 2, 100, 200, 100), "" + enemyMonster.Name);
GUI.Label (new Rect (Screen.width / 2, 110, 200, 100), "HP " + enemyMonster.curHP + "/" + enemyMonster.baseHP);
//Player monster
GUI.Label (new Rect (50, 100, 200, 100), "" + monsterEquiped.Name);
GUI.Label (new Rect (50, 110, 200, 100), "HP " + monsterEquiped.curHP + "/" + monsterEquiped.baseHP);
}
}
using UnityEngine;
using System.Collections;
public class TurnBasedCombatStateMachine : MonoBehaviour {
private BattleStateStart battleStateStartScript = new BattleStateStart();
//The different states
public enum Battlestates{
START,
PLAYERCHOICE,
ENEMYCHOICE,
LOSE,
WIN,
CALCULATEDAMAGE,
ADDSTATUSEFFECTS
}
private Battlestates currentState;
// Use this for initialization
void Start () {
currentState = Battlestates.START;
}
// Update is called once per frame
void Update () {
Debug.Log (currentState);
switch (currentState) {
case(Battlestates.START):
battleStateStartScript.PrepareBattle(); //<<<<< Calling randomizeMonster by calling PreparBattle
// doesn't work, gives
// NullReferenceException: Object reference
// not set to an instance of an object
break;
case(Battlestates.PLAYERCHOICE):
break;
case(Battlestates.ENEMYCHOICE):
break;
case(Battlestates.CALCULATEDAMAGE):
break;
case(Battlestates.ADDSTATUSEFFECTS):
break;
case(Battlestates.LOSE):
break;
case(Battlestates.WIN):
//Add XP
break;
}
}
//Change state button
void OnGUI(){
if(GUILayout.Button("Next State")){
if(currentState==Battlestates.START){
currentState=Battlestates.PLAYERCHOICE;
}else if(currentState==Battlestates.PLAYERCHOICE){
currentState=Battlestates.ENEMYCHOICE;
}else if(currentState==Battlestates.ENEMYCHOICE){
currentState=Battlestates.LOSE;
}else if(currentState==Battlestates.LOSE){
currentState=Battlestates.WIN;
}else if(currentState==Battlestates.WIN){
currentState=Battlestates.START;
}
}
}
}
You should check if anything is null by printing things out.
Right before the line that causes the errors, put this
Debug.Log(All$$anonymous$$onsters);
for (int i = 0; i < All$$anonymous$$onsters.Length; i++) {
Debug.Log(All$$anonymous$$onsters[i]);
}
Do the same thing for line 109:
Debug.Log(battleStateStartScript);
If you see anything that is null, then that's the problem.
Thanks for the reply, I did as you said with the debug.log. I ran the script and called randomize$$anonymous$$onster once in start() and it works, the debug.log shows that the array isn't null. Then the state machine calls randomize$$anonymous$$onster and it reports that the array is null. It reports already in the for statement.
The gameobject with the scripts, shows that the public array isn't null either. How can it work from just update and start?
Did you check battleStateStartScript
? You're creating a component but not actually assigning it to a GameObject.
Does the State$$anonymous$$achine have the correct reference to the class?
What is the line of that error?
Answer by Primex · Sep 06, 2015 at 08:04 PM
Thanks cj and Crypto! The problem was: private BattleStateStart battleStateStartScript = new BattleStateStart(); Insted of calling the script i had put on my GO i created a new one, in which the array length was null.
Solved it by using GetComponent to find my script:D
$$anonymous$$ost welcome!
Thinking it back it was quite obvious, since the issue only occurred in the state machine