Search Unity

PrefabUtility.ConnectGameObjectToPrefab with Undo

Discussion in 'Immediate Mode GUI (IMGUI)' started by Xarbrough, Jul 29, 2017.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    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:
    7
    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.
     
  3. Pangamini

    Pangamini

    Joined:
    Aug 8, 2012
    Posts:
    54
    Any solution yet? Would it be sufficient to destroy the original object, instantiate the prefab (at the same position and parent) and record that action? What about unrelated children objects?