- Home /
2D Array keeps coming up as Null
Hi, I'm trying to create a 2d board in unity using a 2d array, but for some reason when trying to add an object to the 2d array it still comes out as null.
public class BlockPlacementTest : MonoBehaviour {
public GameObject floor;
public int size;
public int width, height;
private int[,] goalCoords;
private List<Room> goalRooms;
private Room[,] rooms;
// Use this for initialization
void Start () {
rooms = new Room[width,height];
createDungeon(10);
printArray();
}
// Update is called once per frame
void Update () {
}
public void createDungeon(int g){
goalRooms = new List<Room>();
rooms = new Room[width,height];
goalCoords = new int[g,2];
for(int i =0; i < g; i++){
int x = (int)(Random.Range(0,rooms.GetLength(0)));
int y = (int)(Random.Range(0,rooms.GetLength(1)));
//Makes sure there isn't any repeats
while(rooms[x,y] != null){
x = (int)(Random.Range(0,width));
y = (int)(Random.Range(0,height));
}
goalCoords[i,0] = x;
goalCoords[i,1] = y;
print("X: "+x+" Y: "+y);
// Room r = new Room(0,size,goalCoords[i,0]*size,goalCoords[i,1]*size);
// r.createBlocks(true);
goalRooms.Add(rooms[x,y] = new Room(0,size,goalCoords[i,0]*size,goalCoords[i,1]*size));
print(rooms[x,y]);
}
connectBlocks();
// for( int i = 0; i < width; i++){
// for(int j = 0; j < height; j++){
// if(rooms[i,j] == null){
// rooms[i,j] = new Room(1,size,i*size,j*size);
// }
// }
// }
}
Room Code:
public class Room : MonoBehaviour {
public GameObject block;
private int type;
private int size;
private int x,y;
private int w,h;
private int numbOfBlocks;
private int[,] blocks;
public Room(int t, int s, int x, int y){
type = t;
size = s;
this.x = x;
this.y = y;
w = 16;
h = w;
blocks = new int[size,size];
createRoom();
createBlocks(false);
}
private void createRoom(){
if(type !=1)
for(int c = 0; c< size; c++){
int by = (int)(Random.Range(0,size));
int bx = (int)(Random.Range(0,size));
if(blocks[bx,by] != 1){
blocks[bx,by] = 1;
}
}
else
for( int i = 0; i < size; i++)
for(int j = 0; j < size; j++)
blocks[i,j] = 1;
}
public void createBlocks(bool goal){
for(int xb = 0; xb < blocks.GetLength(0); xb++){
for(int yb = 0; yb < blocks.GetLength(1); yb++){
if(blocks[xb,yb] == 1){
// Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube),new Vector3(xb+x,0,yb+y), Quaternion.identity);
var wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
// wall.AddComponent(Rigidbody);
wall.transform.position = new Vector3(xb+x,0,yb+y);
if(goal)
wall.renderer.material.color = new Color(0,0,0);
else
wall.renderer.material.color = new Color(1,1,1);
}
}
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public int[,] getBlocks(){
return blocks;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getArrayX(){
return x/size;
}
public int getArrayY(){
return y/size;
}
public int getRoomType(){
return type;
}
}
Any possible reasons why it keeps printing null?
Nowhere if the code you've pasted do you initialise rooms[], without seeing where you've set rooms[] it's expected to return null.
Post all relevant code, otherwise we might not be able to help (include your Room script)
Answer by Bunny83 · Jun 19, 2014 at 12:53 AM
Well, the answer is simple:
You created a MonoBehaviour with "new"!
You can't create MonoBehaviours (or any kind of Component) manually. You always have to use AddComponent. Components can only "live" on GameObjects. If you create a MonoBehaviour with new, it's missing it's native part and it "fakes" itself to be null. The same happens when you destroy a component. As you might know in managed environments you usually can't destroy objects. Objects are garbage collected when all references to that object are gone.
However components can be destroyed (they are actually C++ objects, the C# class is "just" the managed counterpart). When you Destroy() a component (or any other object derived from UnityEngine.Object) the native part get destroyed but the managed part will be there until it's garbage collected once all references are gone. The managed object has an internal flag that it's actually dead. The UnityEngine.Object has overridden the Equals and ==operator to fake the reference is null.
You shouldn't implement a constructor on MonoBehaviour classes. Instead you can implement a create method like this:
public static Room Create(int t, int s, int x, int y)
{
GameObject GO = new GameObject("Room_"+x+"_"+y);
Room R = GO.Addcomponent<Room>();
R.type = t;
R.size = s;
R.x = x;
R.y = y;
R.w = 16;
R.h = w;
R.createRoom();
R.createBlocks(false);
return R;
}
this method will create a new GameObject with a Room script attached, will initialize your desired variables and return the reference to the Room component.
Okay thanks, but I do have one question. How can I use the addComponent with the array and the list? Edit: Never $$anonymous$$d it works. Thank you again!
Your answer
Follow this Question
Related Questions
Object is null when it shouldn't be. 1 Answer
How to remove null's from 2d array ? It's removing but only 2 out of 4 null's. 0 Answers
Calling prefabs by name or tag returns null. 1 Answer
arrays are giving me null reference exceptions and I don't know why 1 Answer
Function like string.IsNullOrEmpty(var) but for arrays 1 Answer