- Home /
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)
Editing the question to include a copy of the error message reported in the Console plus placing a comment at the line $$anonymous$$ono reports as having the error will promote getting this question answered faster and more accurately.
Answer by Eric5h5 · Mar 12, 2013 at 12:41 AM
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.)
Answer by PsychoHead · Mar 12, 2013 at 12:35 AM
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)
Oh, of course. That was me never using Unityscript. ;)
Have you perhaps just forgotten to assign an actual GameObject to the variable menu_text_prefab
either in the editor or through another Script?
Answer by apeshake · Mar 14, 2013 at 12:35 PM
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);
}
}
}
I finally got it, thanks Eric5h5 !
At first I didn't fully get how a class constructor worked but now i do, for anyone interested the script below now works
now I can finally get on with sorting out the layout,highlighting etc for the menu!
#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;
//class constructor:
function ShopLine (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);
Display$$anonymous$$enu ();
}
function Display$$anonymous$$enu(){
shop_lines = new ShopLine[ship_upgrade_array.Length];
for (var line_number : int = 0; line_number < ship_upgrade_array.Length; line_number++){
Debug.Log("we have " + shop_lines.Length + " shop lines");
if (shop_lines[line_number] == null){// instantiate the prefabs:
var n : GameObject = GameObject.Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity);
var c : GameObject = GameObject.Instantiate(menu_text_prefab,Vector3(0,0,0),Quaternion.identity);
//fill the array with the new prefabs:
shop_lines[line_number] = new ShopLine(n,c,line_number);
Debug.Log("this is line number " + line_number);
}
}
}