Hey there. I’ve got an editor script that finds a nested prefab, instantiates it, modifies properties of it, and now I want to copy those changes from the instance back to the prefab (and then delete the instance).
My code works great, right up to the point where it’s time to save it back to the prefab. I had thought that I could use the ReplacePrefab(GameObject, Prefab) method. However, attempting to do this halts Unity and then crashes to desktop.
Is this what ReplacePrefab should do? Examples I’ve seen of this have always used the CreateEmptyPrefab, and then done a replace() method on the new prefab. In this case, I’m trying to update an existing prefab, rather than create a new one.
Thanks for any insight.
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Text;
public class BuildSkinList
{
[MenuItem("Assets/SHS/Build Skin List")]
public static void DoIt()
{
UnityEngine.Object apfab;
UnityEngine.Object uifab;
GameObject uigo;
// Get the GUI Manager refernece in the scene. Warning, heavily nested... DEEP.
GUIManager gui = getGUIManager( out apfab, out uifab, out uigo);
if (gui == null)
{
Debug.Log("Can't find GUIManager in scene.");
return;
}
// With the reference, go through the project and find anything that's a skin.
// Add the skin to the list in the UI Manager
UnityEngine.Object[] gameObjects = UnityEngine.Object.FindObjectsOfTypeAll(typeof(GUISkin));
foreach (UnityEngine.Object o in gameObjects)
{
gui.testSkinList.Add((GUISkin)o);
Debug.Log(o.name);
}
EditorUtility.ReplacePrefab(uigo, uifab, ReplacePrefabOptions.ReplaceNameBased);
if (apfab != null)
GameObject.DestroyImmediate(apfab);
if (uifab != null)
GameObject.DestroyImmediate(uifab);
}
private static GUIManager getGUIManager(out UnityEngine.Object apfab,
out UnityEngine.Object uifab,
out GameObject uigo
)
{
// Zero out the prefab objs
apfab = null;
uifab = null;
uigo = null;
GUIManager gui = null;
// Get the game controller gameobject for this scene
UnityEngine.GameObject go = GameObject.FindGameObjectWithTag("GameController");
Debug.Log(go);
if (go == null) return gui;
// Get the game controller component itself.
GameController c = go.GetComponent<GameController>();
Debug.Log(c.name);
if (c == null) return gui;
// Get the AppShellPrefab from the game controller component.
GameObject app = c.AppShellPrefab;
Debug.Log(app.name);
if (app == null) return gui;
// Rise, prefab, rise!
apfab = EditorUtility.InstantiatePrefab(app);
Debug.Log(apfab.name);
// Now hunt down the instantiated version by its tag.
UnityEngine.GameObject apgo = GameObject.FindGameObjectWithTag("ApplicationShell");
Debug.Log(apgo);
// Get the AppShell component
AppShell ap = apgo.GetComponent<AppShell>();
Debug.Log(ap.name);
// Get the UIManagerPrefab component from the AppShellComponent.
GameObject uicomp = ap.UIManagerPrefab;
Debug.Log(uicomp.name);
// Rise, ui prefab, rise!
uifab = EditorUtility.InstantiatePrefab(uicomp);
uigo = GameObject.FindGameObjectWithTag("GUIManager");
Debug.Log(uigo.name);
// Finally, whew, get the GUIManager reference and send it BACK to the caller. Boy, are they lucky...
gui = uigo.GetComponent<GUIManager>();
Debug.Log(gui);
return gui;
}
}
[/code]