"ArgumentException: The Object you want to instaintiate is null."

Hi everyone,

Recently I’m getting this ArgumentException while attempting to instantiate a Terrain.

I first click on a button, then the Run() void (code below) is executed.

The exception is thrown at line 33.

Code for LevelLoader.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelLoader : MonoBehaviour {
    public class LevelElemTag
    {
        public Dictionary<string, string> TagProperties = new Dictionary<string, string>();
    }

    public string fileName = "";
	public void Run() {
        if (!System.IO.File.Exists(fileName)) { throw new System.Exception("File " + fileName + " not found!"); };
        //Load file content:
        string[] fileContent = System.IO.File.ReadAllLines(fileName, System.Text.Encoding.Unicode);
        //Process file:
        foreach(string s in fileContent) //For each element (represented as a text line in the file)
        {
            //Read base properties:
            Vector3 position = GetVector3(s,1);
            Quaternion rotation = GetQuaternion(s, 2);
            LevelElemTag data = GetTag(s, 3);
            //What is -s-?
            switch (GetNature(s))
            {
                case "tran":
                    //It's a train model
                    Instantiate(GetTrain(data), position, rotation);
                    break;
                case "terr":
                    //It's a terrain
                    Instantiate(GetTerrain(data), position, rotation);
                    break;
                case "rail":
                    //It's a rail
                    Instantiate(GetRailway(data), position, rotation);
                    break;
                case "deco":
                    //It's a decoration
                    Instantiate(GetDecor(data), position, rotation);
                    break;
                case "virt":
                    //It's an entity (controller, effect...)
                    Instantiate(GetEntity(data), position, rotation);
                    break;
                default:
                    break;
            }
        }

	}
    string GetNature(string line)
    {
        return line.Split('|')[0];
    }
    Vector3 GetVector3(string line,int index)
    {
        string block = line.Split('|')[index];
        float x = 0, y = 0, z = 0;
        try
        {
        x = float.Parse(block.Split(';')[0]);
        y = float.Parse(block.Split(';')[1]);
        z = float.Parse(block.Split(';')[2]);
        }
        catch (System.Exception e)
        {
            throw e;
        }
        return new Vector3(x, y, z);
    }
    Quaternion GetQuaternion(string line, int index)
    {
        string block = line.Split('|')[index];
        float w = 0,x = 0, y = 0, z = 0;
        try
        {
            w = float.Parse(block.Split(';')[0]);
            x = float.Parse(block.Split(';')[1]);
            y = float.Parse(block.Split(';')[2]);
            z = float.Parse(block.Split(';')[3]);
        }
        catch (System.Exception e)
        {
            throw e;
        }
        return new Quaternion(x,y,z,w);
    }
    LevelElemTag GetTag(string line, int index)
    {
        string block = line.Split('|')[index];
        LevelElemTag my = new LevelElemTag();
        foreach (string item in block.Split(';'))
        {
            my.TagProperties.Add(item.Split('=')[0], item.Split('=')[1]);
        }
        return my;
    }

    GameObject GetTrain(LevelElemTag meta)
    {
        GameObject model = (GameObject) Resources.Load("Trains/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]) as GameObject;
        return model;
    }
    Terrain GetTerrain(LevelElemTag meta)
    {
        Terrain model = (Terrain)Resources.Load("Objects/Terrains/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]) as Terrain;
        return model;
    }
    GameObject GetRailway(LevelElemTag meta)
    {
        GameObject model = (GameObject)Resources.Load("Objects/Rails/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]) as GameObject;
        return model;
    }
    GameObject GetDecor(LevelElemTag meta)
    {
        GameObject model = (GameObject)Resources.Load("Objects/Decor/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]) as GameObject;
        return model;
    }
    GameObject GetEntity(LevelElemTag meta)
    {
        GameObject model = (GameObject)Resources.Load("Objects/Entities/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]) as GameObject;
        return model;
    }
}

Directory structure for the terrain:

Assets/Objects/Terrains/debug/grassy.prefab (as in the editor’s Project window)

Values at runtime:

family is debug

type is grassy

Thanks in advance

Lorenzo

Your “Objects” folder is not located in a Resources folder. You can use Resources.Load only for assets stored in a Resources folder. Any other asset is not included in your build when it’s not directly referenced by a script / component.

So the path should be

Assets/Resources/Objects/Terrains/debug/grassy.prefab 

Btw: You currently do a double casting of the result of Resources.Load. Just use the generic version and remove all the casting:

Terrain model = Resources.Load<Terrain>("Objects/Terrains/" + meta.TagProperties["family"] + "/" + meta.TagProperties["type"]);

I also want to note that the way you parse your string is extremely inefficient. string.split will allocate a new array each time it is called.