- Home /
Instantiate prefab using Resources.Load()
Hello, I am trying to instantiate cube(block) depending on which of them is selected in List, but unity writes
"NullReferenceException: Object reference not set to an instance of an object Building.BlockName () (at Assets/Scripts/Building.cs:33) Building.Update () (at Assets/Scripts/Building.cs:21) "
Building script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Building : MonoBehaviour {
private Transform _spawnPosition;
private string _blockName;
void Update() {
_blockName = BlockName();
if(Input.GetKeyUp(KeyCode.Mouse0)) {
Instantiate(Resources.Load(_blockName), _spawnPosition.position, Quaternion.identity);
}
}
string BlockName() {
MainBar mb = GetComponent<MainBar>();
return mb.blocks[mb.selectedItem].Name;
}
}
And here is MainBar script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MainBar : MonoBehaviour {
private float _barWidth;
private float _barHeight;
private int _offset;
private int _barSlots;
private float _iconSize;
private int _iconOffset;
public List<Block> blocks;
public int selectedItem;
// Use this for initialization
void Start () {
_barWidth = Screen.width;
_barHeight = Screen.height/10;
_offset = 100;
_barSlots = 3;
_iconOffset = 10;
_iconSize = _barHeight - _iconOffset;
blocks = new List<Block>();
selectedItem = 0;
//for now we want to add wooden, stone, bricks block to main bar
AddBlock("WoodenBlock", Icons.woodBlockIcon);
AddBlock("StoneBlock", Icons.stoneBlockIcon);
AddBlock("BricksBlock", Icons.bricksBlockIcon);
}
void AddBlock(string name, Texture2D icon) {
Block block = new Block(name, icon);
blocks.Add(block);
}
// Update is called once per frame
void Update () {
}
void OnGUI() {
GUI.Box(new Rect(_offset, Screen.height - _barHeight, _barWidth - 2*(_offset), _barHeight), string.Empty);
for(int i = 0; i < _barSlots; i++) {
if(GUI.Button(new Rect(_offset + i *(_iconOffset + _iconSize), Screen.height - _iconSize - _iconOffset/2, _iconSize, _iconSize), blocks[i].Icon)) {
selectedItem = i;
}
}
}
}
And very simple Block class:
using UnityEngine;
public class Block : MonoBehaviour {
private string _name;
private Texture2D _icon;
public Block(string name, Texture2D icon) {
_name = name;
_icon = icon;
}
#region Getters and Setters
public string Name {
get { return _name; }
set { _name = value; }
}
public Texture2D Icon {
get { return _icon; }
set { _icon = value; }
}
#endregion
}
I will be grateful for any help.
Answer by KellyThomas · Dec 27, 2013 at 01:23 PM
I you have unexpected null references and can't see where they are coming from attaching a debugger and stepping though the code is often the best strategy.
Another strategy is to test any assumptions and intermediate results and print step by step updates to the console or log.
Please try replacing the BlockName
method with this code and check the console for messages.
string BlockName() {
MainBar mb = GetComponent<MainBar>();
if(mb == null) {
Debug.Log("MainBar not found");
return "Error";
}
if(mb.blocks == null) {
Debug.Log("mb.blocks is null");
return "Error";
}
Debug.Log("mb.selectedItem: " + mb.selectedItem);
Debug.Log("mb.blocks.Count: " + mb.blocks.Count);
Block block = mb.blocks[mb.selectedItem];
if (block == null) {
Debug.Log("block is null");
return "Error";
}
Debug.Log("block.Name: " + block.Name);
return block.Name;
}
Bingo! Is $$anonymous$$ainBar attached to the same GameObject or another?
How could I made such a mistake :D. Thanks a lot both of you!
Answer by Tomer-Barkan · Dec 27, 2013 at 12:31 PM
Make sure that the string passed to resources.load is indeed an actual prefab name. You can add a debug log just before and print _blockName.
Use the generic version of Resources.Load: Resources.Load()
Make sure that your prefabs are under a directory named "Resources". They must be under a Resources directory to use Resources.Load.
Make sure that
spawnPosition
is correctly defined and not null.void Update() { _blockName = BlockName(); if(Input.GetKeyUp(KeyCode.Mouse0)) { Debug.Log("Instantiating prefab: " + _blockName + " at position " + _spawnPosition.position); Instantiate(Resources.Load<GameObject>(_blockName), _spawnPosition.position, Quaternion.identity); } }
Point 4. and 3. are correctly as long as it works for one, specific object. But strange is, that when I added Debug.Log into it as you said, it doesn't even appear. Now I really don't know what is wrong.
Now I added
$$anonymous$$ainBar mb = GetComponent<$$anonymous$$ainBar>();
Debug.Log(mb.selectedItem);
to very start of Update function and it didn't appear too. There must be problem in instantiating class...
If you're getting the null pointer exception in the line of the debug, the only thing that can be is that _spawnPosition
is null. $$anonymous$$ake sure you give it a value.
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Follow and Instantiated Object 0 Answers
Multiple Cars not working 1 Answer
[SOLVED]: Bullets passing through platforms - Brackeys Tutorial 1 Answer