- Home /
PrefabUtility.InstantiatePrefab returns Null in Editor
When I use regular Instantiate it returns the selected object I selected in the editor window and creates clones for me. BUT I want to use the PrefabUtility.InstantiatePrefab so every clone keeps the prefab connection. Problem is that PrefabUtility.InstantiatePrefab returns Null for me. You can easily try both Instantiate and PrefabUtility.InstantiatePrefab by removing my comments in the code below.
Thank you for your time.
using UnityEditor;
using UnityEngine;
public class MyWindow : EditorWindow
{
public GameObject useGameObject;
[MenuItem ("Tools/Replace %g")]
public static void Replace()
{
EditorWindow.GetWindow(typeof(MyWindow));
}
void OnGUI ()
{
GUILayout.Label ("Use Object", EditorStyles.boldLabel);
useGameObject = EditorGUILayout.ObjectField(useGameObject, typeof(GameObject), true) as GameObject;
if (GUILayout.Button ("Replace Objects"))
{
foreach (Transform t in Selection.transforms)
{
Debug.Log(useGameObject);
// BELOW DOES NOT WORK
//GameObject newObject = PrefabUtility.InstantiatePrefab(useGameObject) as GameObject;
// BELOW WORKS
GameObject newObject = Instantiate(useGameObject) as GameObject;
Debug.Log(newObject);
Transform newT = newObject.transform;
newT.position = t.position;
newT.rotation = t.rotation;
newT.localScale = t.localScale;
newT.parent = t.parent;
}
}
}
}
Did you comment out the line with the PrefabUtility before running? And yes I drag a prefab, from the hierarchy list in to the object field thus assigning it to useGameObject.
And thank you for helping!
EDIT: Now I understand that there is a difference between scene objects and prefabs.
Yeah, if you're dragging from the Hierarchy, you are grabbing a scene gameobject, even if it is blue. If it's blue, it just means its a scene gameobject instanced from a prefab, but isn't actually the prefab itself. You'll need to reference it from the project window, but I'm assu$$anonymous$$g that you've already made it that far since you got it working! :) I'm converting my comment to an answer since this seems to be the push-in-the-right-direction you needed to get your question answered.
Answer by eightbitstev · Mar 19, 2014 at 01:32 PM
I just tried out your code and it works perfectly for me. Is it possible that you've assigned useGameObject to a scene object instead of a prefab by accident?
EDIT: If you're dragging from the Hierarchy, you are grabbing a scene gameobject, even if it is blue. If it's blue, it just means its a scene gameobject instanced from a prefab, but isn't actually the prefab itself. You'll need to reference it from the project window.
Thank you for pushing me in the right direction. I've posted the code that works now. This time it works with prefabs, scene objects and objects!
Answer by mrBeam · Mar 19, 2014 at 03:25 PM
Got it to work! Now it can handle scene objects, prefabs and objects! Enjoy =)
using UnityEditor;
using UnityEngine;
public class ReplaceSel : EditorWindow
{
GameObject myObject;
[MenuItem ("Tools/ReplaceSelected %g")]
public static void ReplaceObjects() {
EditorWindow.GetWindow(typeof(ReplaceSel));
}
void OnGUI () {
GUILayout.Label ("Use Object", EditorStyles.boldLabel);
myObject = EditorGUILayout.ObjectField(myObject, typeof(GameObject), true) as GameObject;
if (GUILayout.Button ("Replace Selected")) {
if (myObject != null) {
foreach (Transform t in Selection.transforms) {
GameObject o = null;
o = PrefabUtility.GetPrefabParent(myObject) as GameObject;
if (PrefabUtility.GetPrefabType(myObject).ToString() == "PrefabInstance") {
o = (GameObject)PrefabUtility.InstantiatePrefab(o);
PrefabUtility.SetPropertyModifications(o, PrefabUtility.GetPropertyModifications(myObject));
}
else if (PrefabUtility.GetPrefabType(myObject).ToString() == "Prefab") {
o = (GameObject)PrefabUtility.InstantiatePrefab(myObject);
}
else {
o = Instantiate(myObject) as GameObject;
}
Undo.RegisterCreatedObjectUndo(o, "created prefab");
Transform newT = o.transform;
newT.position = t.position;
newT.rotation = t.rotation;
newT.localScale = t.localScale;
newT.parent = t.parent;
foreach (GameObject go in Selection.gameObjects) {
Undo.DestroyObjectImmediate(go);
}
}
}
}
}
}