How can I instantiate a GameObject directly into an array?

I’m trying to create a dynamic in-game menu that instantiates a gameObject (with a GUIText component) for each option in the menu. I’ve got a script with a for loop which is supposed to instantiate a GameObject prefab (actually 2 per line) depending on the number of options specified in the inspector.

the script does compile, i’ve assigned a prefab and i’ve checked with debugs that the for loop runs as i expect it to but i get an error at runtime;

NullReferenceException: Object reference not set to an instance of an object
ShopLogic.DisplayMenu () (at Assets/scripts/ShopLogic.js:51)
ShopLogic.Start () (at Assets/scripts/ShopLogic.js:42)

I’m pretty new to javascript (and programming in general) and don’t yet have a full grasp of how arrays work so if anyone can point out what i’m doing wrong i’d really apprectiate it.

The script is below (sorry there’s quite a bit in there that’s not totally relevant yet but thought it best to show the whole thing);

    #pragma strict
 
var menu_text_prefab : GameObject;
 
class ShipUpgradeItem {
    var name : String;
    var ship_upgrade_function_call : String;
    var cost : int;
    var cost_increase : float;
    var cost_increase_multiply : boolean;
    var upgrade_unlocked : boolean;
    var max_upgrade_allowance : int;
}
var ship_upgrade_array : ShipUpgradeItem[];
 
class ShopLine {
    var shop_line_name : GameObject;
    var shop_line_cost : GameObject;
}
 
var shop_lines : ShopLine[];
 
var cost_colour : Color = Color(1,1,0,1);
var available_colour : Color = Color(1,1,1,1);
var unavailable_colour : Color = Color(1,0,0,0.8);
var highlight_colour : Color = Color(0,1,0,1);
 
private var this_line_colour : Color;
var line_0_y_position : float = 0;
var y_spacing : float = -25;
var left_alignment : float = -225;
var right_alignment : float = 125;
var far_right_alignment : float = 225;
 
var in_game_logic : InGameLogic;
private var player_pressed_continue : boolean = false;
private var game_state : GameState;
 
function Start (){
    in_game_logic = GameObject.Find("InGameLogicHolder").GetComponent(InGameLogic);
    game_state = GameObject.Find("GameStateHolder").GetComponent(GameState);
    DisplayMenu ();
}
 
function DisplayMenu(){
    shop_lines = new ShopLine[ship_upgrade_array.Length];
    Debug.Log("we have " + shop_lines.length + " shop lines");
    var line_number : int = 0;
    for (ShipUpgradeItem in ship_upgrade_array){
       Debug.Log("line " + line_number);//next line gives NullReferenceException error
       shop_lines[line_number].shop_line_name = Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity);
       shop_lines[line_number].shop_line_name.GetComponent(GUIText).pixelOffset.x = left_alignment;
       shop_lines[line_number].shop_line_cost = Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity);
       shop_lines[line_number].shop_line_cost.GetComponent(GUIText).pixelOffset.x = right_alignment;
       line_number ++;
    }
}

(edited to indicate line that gives error)

You should use the new statement:

shop_lines[line_number].shop_line_name = Instantiate(menu_text_prefab, new Vector3(0,0,0),Quaternion.identity)

or alternatively use Vector3.zero

shop_lines[line_number].shop_line_name = Instantiate(menu_text_prefab,Vector3.zero,Quaternion.identity)

You need to initialize the entries in the shop_lines array. You’ve created the array itself, but all the entries inside are null until they are initialized. (Also I’d recommend making a constructor for your ShopLine class; that will make it easier to initialize the array entries.)

thanks for the advice - the class constructor is a great tip and i’m trying to get this working with that now but still having problems filling the array…

My current script (below) works as i’d expect it to if i comment out the “shop_lines[line_number].FillShopLine…” function, otherwise i get the error;

NullReferenceException: Object reference not set to an instance of an object
ShopLogic.DisplayMenu () (at Assets/scripts/ShopLogic.js:57)
ShopLogic.Start () (at Assets/scripts/ShopLogic.js:48)

I have tried including the Instantiate function in the class constructor instead of the For Loop but i still get the same error

In the scene i’ve noticed the For loop does get to the instantiate functions and instantiates the first two text_menu_prefab gameObjects, but they do net get put into the array. I can also see in the inspector that the array has been set to the correct length (at the moment that’s just 3 to keep things simple).

Sorry if i’m being slow but i can’t seem to find any way to initialise the array but this (or the original version i posted of this script…) is there some basic principle i’m missing?

(PS i definitely have assigned a prefab to the var menu_text_prefab)

#pragma strict
 
var menu_text_prefab : GameObject;
 
class ShipUpgradeItem {
    var name : String;
    var ship_upgrade_function_call : String;
    var cost : int;
    var cost_increase : float;
    var cost_increase_multiply : boolean;
    var upgrade_unlocked : boolean;
    var max_upgrade_allowance : int;
}
var ship_upgrade_array : ShipUpgradeItem[];
 
class ShopLine {
    var shop_line_name : GameObject;
    var shop_line_cost : GameObject;
    var shop_line_number : int;
    function FillShopLine (name : GameObject,cost : GameObject,number : int){
		this.shop_line_name = name;
    	this.shop_line_cost = cost;
    	this.shop_line_number = number;
    }
}
 
var shop_lines : ShopLine[];
 
var cost_colour : Color = Color(1,1,0,1);
var available_colour : Color = Color(1,1,1,1);
var unavailable_colour : Color = Color(1,0,0,0.8);
var highlight_colour : Color = Color(0,1,0,1);
 
private var this_line_colour : Color;
var line_0_y_position : float = 0;
var y_spacing : float = -25;
var left_alignment : float = -225;
var right_alignment : float = 125;
var far_right_alignment : float = 225;
 
var in_game_logic : InGameLogic;
private var player_pressed_continue : boolean = false;
private var game_state : GameState;
 
function Start (){
    in_game_logic = GameObject.Find("InGameLogicHolder").GetComponent(InGameLogic);
    game_state = GameObject.Find("GameStateHolder").GetComponent(GameState);
    DisplayMenu ();
}
 
function DisplayMenu(){
	shop_lines = new ShopLine[ship_upgrade_array.Length];
	for (var line_number : int = 0; line_number < shop_lines.Length; line_number++){
		Debug.Log("we have " + shop_lines.Length + " shop lines");
		if (shop_lines[line_number] == null){
			//following line gives a NullReferenceException error 
			shop_lines[line_number].FillShopLine(
			GameObject.Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity),
			GameObject.Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity),
			line_number);
			Debug.Log("this is line number " + line_number);
		}
	}
}