prefab is null error

I’m using a script to instantiate a model multiple times as in the brick wall example in the Unity manual - the code is more or less identical and I’ve followed the steps closely. I’ve imported a model and dragged it onto the script variable. But when I run the script I get this error, and I can’t figure out what I’m missing:

NullReferenceException: the prefab you want to instantiate is null

Anyone got any ideas? thanks!

A model isn’t a prefab. Does the prefab variable look like it has something in it after you dragged the model to it?

sorry, I should have said that I added the model to the prefab, and dragged the prefab to the script variable - just following the steps in the manual

More details please, like your script if you don’t mind. Even you said it’s mostly the same, perhaps there’s an ever so small difference there?

Also, did you drag-assign the prefab while the game is playing in Unity, then hit stop, then restart and now get the error? Changes made while the content is running are flushed so you’ll need to stop the game, reassign the prefab (and hit save :slight_smile: ), then press play again.

And to be specific, you dragged the prefab from your Project view on to the variable in the inspector right? (as opposed to dragging the in-scene version of it from the Hierarchy view)

Hi Tom, thanks for helping me out. Here goes…

var aBlock : Transform;
private var xpos = 1036;
private var ypos = 80;
private var zpos = 797;
private var gutter = 3;

// when game starts, layout initial rows of objects
function Start () {
createGrid();
}

function createGrid () {
var uniqueNum = 0;
// create 8 rows x 6 columns of objects
for (var countY = 1; countY < 7; countY++) {
for (var countZ = 1; countZ < 9; countZ++) {
x = xpos;
y = ypos + countY * gutter;
z = zpos + countZ * gutter;
// create the object and two duplicates at sides (for slide operations)
var aBlock = Instantiate(aBlock, Vector3(x, y, z), Quaternion.identity);
uniqueNum++;
aBlock.name = “obj_”+uniqueNum;
// change colour randomly
var randomcolour = Random.Range(1, 7);
// and ensure far left and right blocks are duplicate colours
if (countZ == 1) var rememberMeA = randomcolour;
if (countZ == 2) var rememberMeB = randomcolour;
if (countZ == 7) randomcolour = rememberMeA;
if (countZ == 8) randomcolour = rememberMeB;
switch (randomcolour)
{
case 1: aBlock.renderer.material.color = Color.red; break;
case 2: aBlock.renderer.material.color = Color.green; break;
case 3: aBlock.renderer.material.color = Color.blue; break;
case 4: aBlock.renderer.material.color = Color.yellow; break;
case 5: aBlock.renderer.material.color = Color.cyan; break;
case 6: aBlock.renderer.material.color = Color.magenta; break;
}
}
}
}

In answer to your questions:

  • I’ve assigned the prefab when the game is not running (and just tried while it is running - no luck)
  • I’m dragging from the ‘Project’ panel to the ‘Inspector’ panel so I think yes to that one

I’m wondering if there’s something wrong with my c4d file - I don’t mind sharing that if you can acertain anything from it…

thanks again!

This line is your problem:

var aBlock = Instantiate(aBlock, Vector3(x, y, z), Quaternion.identity);

var aBlock creates a local variable aBlock (that is null) that masks the “global” (actually instance) variable aBlock you thought you were using on the right hand side. Rename the new variable and it should work (or at least misbehave elsewhere).

It seems to me this should cause a compile-time error, or at least a warning.

I never quite understood why the variables are repeated like that but changing one of them didn’t appear to help. Here’s the code I have right now, which is throwing the same error. I get the error at runtime only, by the way.

var aBlock : Transform;
var bBlock : Transform;

// when game starts, layout initial rows of objects
function Start () {
createGrid();
}

function createGrid () {
var uniqueNum = 0;
// create 8 rows x 6 columns of objects
for (var countY = 1; countY < 7; countY++) {
for (var countZ = 1; countZ < 9; countZ++) {
x = xpos;
y = ypos + countY * gutter;
z = zpos + countZ * gutter;
// create the object and two duplicates at sides (for slide operations)
var aBlock = Instantiate(bBlock, Vector3(x, y, z), Quaternion.identity);
uniqueNum++;
aBlock.name = “obj_”+uniqueNum;
}
}
}

Ah I think I have just solved the problem. I just tried attaching the script to the prefab, and then reassigning the prefab to the variable, and it’s now working. It appears that it only works if there’s an instance of the prefab in the scene from the start too. Can’t say I really understand why that works, but it apparently does!

I know you seem to have got things working but you’re doing stuff wrong (I think) and I’d like to explain. First off, your last chunk of code (the relevant bits) was:

var aBlock : Transform;
var bBlock : Transform;

// when game starts, layout initial rows of objects
function Start () {
  createGrid();
}

function createGrid () {
  ...
  for (var countY = 1; countY < 7; countY++) {
    for (var countZ = 1; countZ < 9; countZ++) {
      ...
      var aBlock = Instantiate(bBlock, Vector3(x, y, z), Quaternion.identity);
      uniqueNum++;
      aBlock.name = "obj_"+uniqueNum;
    }
  }
}

First off, why are you declaring aBlock as a variable twice? You do it once at the top of your script then again inside your createGrid() function. If you’ve already declared aBlock at the top then you don’t need to do it again in your function. Also, it might help A LOT to use better variable names, something like this:

var prefabBlock : Transform;

// when game starts, layout initial rows of objects
function Start () {
  createGrid();
}

function createGrid () {
  ...
  for (var countY = 1; countY < 7; countY++) {
    for (var countZ = 1; countZ < 9; countZ++) {
      ...
      var instantiatedBlock = Instantiate(prefabBlock, Vector3(x, y, z), Quaternion.identity);
      uniqueNum++;
      instantiatedBlock.name = "obj_"+uniqueNum;
    }
  }
}

With the code written as above you would drag your prefab from the Project pane to the inspector and assign it as the value for the prefabBlock block variable. Notice that I removed the declaration for the other block variable at the top as it seems that you’re not keeping references to all instantiated blocks anyway.

Why are you attaching this script to the prefab at all? Doing that is what requires you to have the prefab in the scene (so the script is in the scene).

thanks, I will tidy things up as you mentioned. Truth is javascript is very new to me and I’m struggling a bit. I do appreciate the help. By the way I generally do use very obvious variable - you caught me at a weak moment - but I think part of my confusion is the sample of code on the script reference page where they use the variable name ‘cube’ for both variables in the line where the prefab is instantiated. I think you called it masking of something? Anyway thanks again, I’d rather get things right and understand how, and you are being very generous with your help. :slight_smile:

Keep us posted as to how this goes, especially if you need more help or clarity. Good luck and have fun! :smile:

Just wanted to say thank you, and I got it to work after cleaning up my code. It looks like I had my variables for the prefab and the instantiated object the wrong way round at some points. I’ve got a much better understanding of instantiation now. Thanks!