How do I use PrefabUtility.InstantiatePrefab() ?

I’m extending the Transform editor with a button that clones game objects in the direction that I want.

For GOs that don’t have a prefab connection, it simply uses Instantiate, and it works great, including setting the clone’s transform parent as the same as the original GO.

If they have a prefab connection, I want the clone to preserve it, which is why I’m also using PrefabUtility.InstantiatePrefab. Unlike Instantiate, it doesn’t take parameters to set the position.

Here’s the relevant piece of the code:

public void CloneGO(string dir)
    {
        int i = 0;
        float originalPosX = obj.transform.position.x;
        float originalPosY = obj.transform.position.y;

        while (i < clones)
        {
            i++;

            if (dir == "up")
            {
                newPos = new Vector2(originalPosX, originalPosY + (i * 0.4f));
            }

            // Other code here

            bool isPrefab = PrefabUtility.IsPartOfPrefabInstance(obj);
            // For Reddit: obj is Selection.activeGameObject;

            if (isPrefab)
            {
                Debug.Log("Cloned a prefab");
                cloneObj = PrefabUtility.InstantiatePrefab(obj) as GameObject;
                cloneObj.transform.position = newPos;
            }

            else
            {
                Debug.Log("Cloned a regular GO");
                cloneObj = Instantiate(obj, newPos, Quaternion.identity);
            }

            cloneObj.transform.parent = obj.transform.parent;

        }

I’m getting a NullReferenceException when I try to clone a prefab. I also know that clone.Obj returns null in the line cloneObj = PrefabUtility.InstantiatePrefab(obj) as GameObject; but I don’t understand why.

I just ran across this myself so I wanted to post what I learned for others who may come to this question later as I did.

The PrefabUtility seems to require that the an object with the file type .prefab. I had some assets that I had simply named with ‘.asset’ and while unity seemed to still recognize it, the utility definitely didn’t.

I passed the full object via the AssetDatabase, as I didn’t have it as a property on a monobehavior where I was using it:

Object obj =  PrefabUtility.InstantiatePrefab(
                        AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/Prefabs/Location.prefab"));