Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

PrefabUtility.ConnectGameObjectToPrefab with Undo

Discussion in 'Extensions & OnGUI' started by Xarbrough, Jul 29, 2017.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    289
    How can I make https://docs.unity3d.com/ScriptReference/PrefabUtility.ConnectGameObjectToPrefab.html work with Undo?

    I've tried Undo.RecordObject, but I'v soon noticed, that the PrefabUtility actually destroys the previous GameObject instance in the scene, then instantiates a new one from the prefab and copies the last instance settings.

    Is it possible to record undo steps for this?

    I've also noticed, that the Transform data is overriden on the new instance, although all other properties seem to be handled correctly (meaning, if they are different from the prefab, they won't be changed, but show up as bold labels instead). Is this a bug or am I not using the feature correctly?

    Code (CSharp):
    1. public GameObject target;
    2. public GameObject prefab;
    3.  
    4. void MyEditorFunction()
    5. {
    6.     // Undo.RecordObject(target); // Doesn't work, because target will be destroyed.
    7.     // Undo.RegisterFullObjectHierarchyUndo(target); // This even crashes Unity and corrupts the scene file permanently.
    8.     // -> Reported in case 936220
    9.     PrefabUtility.ConnectGameObjectToPrefab(targets, prefab);
    10. }
     
  2. RupeOxVR

    RupeOxVR

    Joined:
    Jul 18, 2018
    Posts:
    1
    This is late but just having coming across this issue myself and seeing there's no answer yet....

    I think you need to record the changes and then reapply them. That's what I'm doing, at least. So something like....

    Code (CSharp):
    1. Vector3 pos = target.transform.pos;
    2. target = PrefabUtility.ConnectGameObjectToPrefab(target, prefab);
    3. target.transform.position = pos;
    Crucially, because as you say ConnectObjectToPrefab destroys and recreates the object, you need to grab its return value (which is the new object) and use that in place of your previous reference.

    ConnectObjectToPrefab is a terrible name for a function that destroys the thing you pass in to it. It would have saved me a day's work if they'd named it more appropriately.