- Home /
NullReferenceException when sending message to another object...really stumped.
Ok, I'm really stumped on this one because this works for some of my objects, but not the PlayerObject. I have it set up that when an object initializes, it sends a message to the TurnController object to add itself to a list to be tracked. This works fine for both my planet objects and my ship objects, but when I attempted to do the same for my player objects, I keep getting a null reference exception saying that the object reference is not set to an instance of an object. This is confusing the heck out of me because I'm essentially re-using the working code from my planet and ship scripts for sending the message to add itself to the list stored by the turn controller.
Here's my turn controller script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TurnControllerScript : MonoBehaviour
{
List<GameObject> allPlanets;
List<GameObject> allShips;
List<GameObject> allPlayers;
public int currentTurnMST = 1;
//public GameObject currentPlayer = null;
// Use this for initialization
void Start ()
{
allPlanets = new List<GameObject>();
allShips = new List<GameObject>();
allPlayers = new List<GameObject>();
}
// Update is called once per frame
void Update ()
{
}
//Execute all actions when Next Turn button is pressed
void NextTurn()
{
currentTurnMST = currentTurnMST + 1;
Debug.Log ("NextTurn has been called");
foreach(GameObject obj in allPlanets)
{
obj.SendMessage ("OnTurnEnd", SendMessageOptions.DontRequireReceiver);
}
foreach(GameObject obj in allShips)
{
obj.SendMessage ("OnTurnEnd", SendMessageOptions.DontRequireReceiver);
}
}
void AddToList(GameObject sentObject)
{
if(sentObject.tag == "Planet")
{
allPlanets.Add (sentObject);
}
if(sentObject.tag == "Ship")
{
allShips.Add (sentObject);
}
if(sentObject.tag == "PlayerObject")
{
allPlayers.Add (sentObject);
Debug.Log ("Added " + sentObject + " to list.");
}
}
void RemoveFromList(GameObject sentObject)
{
if(sentObject.tag == "Planet")
{
allPlanets.Remove (sentObject);
}
if(sentObject.tag == "Ship")
{
allShips.Remove (sentObject);
}
if(sentObject.tag == "PlayerObject")
{
allPlayers.Remove (sentObject);
}
}
}
And this is the relevant script from both my playerScript (that sends the message from the player object) and my shipScript (does likewise for ship objects when they're created).
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour
{
GameObject turnControl;
TurnControllerScript turnControllerScript;
GameObject guiControl;
GUIControllerScript guiControllerScript;
public int playerNumber = 1;
public string playerName = "Test Name";
// Use this for initialization
void Start ()
{
//Initialize both the turn controller and gui controller connections
turnControl = GameObject.Find ("TurnController");
turnControllerScript = GameObject.Find ("TurnController").GetComponent<TurnControllerScript>();
guiControl = GameObject.Find ("GUIController");
guiControllerScript = GameObject.Find ("GUIController").GetComponent<GUIControllerScript>();
turnControl.SendMessage ("AddToList", gameObject);
}
// Update is called once per frame
void Update ()
{
}
}
using UnityEngine;
using System.Collections;
public class ShipTestScript : MonoBehaviour
{
GUIControllerScript guiControl;
TurnControllerScript turnControl;
...
// Use this for initialization
void Start ()
{
guiControl = GameObject.Find ("GUIController").GetComponent<GUIControllerScript>();
turnControl = GameObject.Find ("TurnController").GetComponent<TurnControllerScript>();
originalMaterial = gameObject.renderer.material;
originPOS = guiControl.selectedObject.transform.position;
targetObject = null;
targetPOS = transform.position;
turnControl.SendMessage ("AddToList", gameObject);
}
The ships are created after the scene loads (during runtime), while the planets and players are set in the scene before hand. The planets and ships both add to their respective lists fine, but I keep getting an exception error with the player objects at the line in the turn controller script that receives the message from the player object. I tried putting the sendMessage call on the player script into the Update instead of Start method and it worked fine, but it's in the Start method in both ship and planet, so I don't understand the disconnect.
Hopefully this makes sense. Help would be immensely appreciated.
Thanks in advance.
Answer by whydoidoit · Aug 10, 2013 at 10:17 PM
The ordering of Start functions in your case is such that the AddToList called by the Start function on one of the classes is called before the Start function on the TurnControllerScript so the lists are null.
Either:
Move the list initialization to an Awake function (I'd do this)
Set the script execution order so that TurnControllerScript executes first
Initialize the lists using
List< GameObject> someList = new List< GameObject>();
in where you define them (I might do this)
Awesome, thank you. I used your first suggestion (move to an Awake function) and it worked beautifully.
Oddly enough, right before I saw your answer, I noticed I wasn't getting any more NullReference errors, even though I hadn't changed anything in those scripts. (I had moved onto working on something else for a bit). But it still wasn't getting added to the list. I just wasn't getting the reference error. But the Awake suggestion solved it anyways.
Ugh. Computers.
Yeah, script execution order causes some hard to find bugs that can sometimes appear as if by magic :S
Could you tick my answer?