Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Breaking a prefab instance for good

Discussion in 'Editor & General Support' started by ArachnidAnimal, Oct 26, 2017.

  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,719
    It is still not possible to completely break a prefab connection to an item in the asset folder. It is very confusing to deal with this.
    I intentionally broke a prefab connection. The "Select, Revert, Apply" buttons still appear on the game object. When clicking on "Select" it still points back to the object in the asset folder.
    The option GameObject-> Break Prefab Instance from the menu bar is grayed out.

    Is the prefab connection broken or is it not broken?
    This results in confusion for us trying to figure out what is going on, especially when using particle system.

    prefab.jpg

    It makes no sense that the buttons would still be shown once the "Break Prefab Instance" is chosen from the menu bar. What is someone accidentally presses the "Revert" or "Apply" button?
    j
     
    Khena_B and Harinezumi like this.
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    13,447
    Please provide specific steps to reproduce.
     
  3. Fatcat-Games

    Fatcat-Games

    Joined:
    Nov 9, 2016
    Posts:
    34
    I am familiar with this bug. If your interested in a work around until Unity can fix it, here is what I do.

    Drag your gameObject from your hierarchy down to the project tab which creates a new prefab.
    Break the prefab instance on the gameObject, and then delete the prefab you just created.
     
  4. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,719
    I'm using Unity 2017.1. It can be reproduced using any of the Standard Assets particle systems.
    1. Drag the "Afterburner" prefab in the scene. (Assets/Standard Assets/ParticleSystems/Prefabs)
    2. Select the gameobject in the hierarchy. Choose GameObject -> Break Prefab Instance from the menu bar
    3. Notice the "Select, Revert, Apply" buttons still appear on the gameobject in the Inspector window.

    For now what I do is create a brand new gameobject. Manually add a Particle System component to it. Then go to the prefab and copy the particle system components (from the gear icon) and paste them into the particle system on the new gameobject. The goal of this is that the gameobject will not "point" to any prefab in the asset folder (to avoid any confusion or accidentally clicking of the Revert or Apply buttons).

    Thanks, I'll try this out in the near future.
     
    Last edited: Oct 27, 2017
    Harinezumi likes this.
  5. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    871
    This is 100% a bug that goes back to 5.6 or even before. Breaking a prefab instance still connects it as if it was never broken.

    I recommend an asset store item called nested prefab -- you can right click the little prefab icon >> break instance. This is what Unity should already have.

    Note, I'm in no way affiliated with the above package, just a happy client to workaround Unity's overflowing bugs~
     
  6. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,719
    Or , use a free script created by Baste:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.     using UnityEditor;
    4.     using UnityEditor.SceneManagement;
    5.    
    6. public static class PermanentlyBreakPrefab {
    7.    
    8.         /// <summary>
    9.         /// From:
    10.         /// http://forum.unity3d.com/threads/breaking-connection-from-gameobject-to-prefab-for-good.82883/
    11.         /// </summary>
    12.         [MenuItem("Utilities/Game Object/Permanently Break Prefab")]
    13.         public static void ExecuteOnSelectedObject() {
    14.             var selected = Selection.gameObjects;
    15.             Selection.activeGameObject = null;
    16.    
    17.             bool dirtyScene = false;
    18.    
    19.             foreach (var gameObject in selected) {
    20.                 var prefabType = PrefabUtility.GetPrefabType(gameObject);
    21.              
    22.                 //Don't do the thing for PrefabType.None (not a prefab), Prefab (prefab asset) or ModelPrefab (model asset)
    23.                 if (prefabType != PrefabType.PrefabInstance &&
    24.                     prefabType != PrefabType.DisconnectedPrefabInstance &&
    25.                     prefabType != PrefabType.ModelPrefabInstance &&
    26.                     prefabType != PrefabType.DisconnectedModelPrefabInstance &&
    27.                     prefabType != PrefabType.MissingPrefabInstance) {
    28.                     continue;
    29.                 }
    30.    
    31.                 dirtyScene = true;
    32.                 PrefabUtility.DisconnectPrefabInstance(gameObject);
    33.                 Object prefab = PrefabUtility.CreateEmptyPrefab("Assets/dummy.prefab");
    34.                 PrefabUtility.ReplacePrefab(gameObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
    35.                 PrefabUtility.DisconnectPrefabInstance(gameObject);
    36.                 AssetDatabase.DeleteAsset("Assets/dummy.prefab");
    37.             }
    38.    
    39.    
    40.             if (dirtyScene) {
    41.                 var sceneCount = EditorSceneManager.sceneCount;
    42.                 for (int i = 0; i < sceneCount; i++) {
    43.                     EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetSceneAt(i));
    44.                 }
    45.             }
    46.         }
    47.     }
    48.  
    49.  
    Put it in an Editor folder.
     
    NeatWolf, luizgpa, Harinezumi and 2 others like this.
  7. Harinezumi

    Harinezumi

    Joined:
    Jan 7, 2013
    Posts:
    54
    Might I suggest a minor improvement? Adding the following line at the end of ExecuteOnSelectedObject and changing the type of selected to GameObject[] will keep the game objects selected (something you usually want, especially if you had a complicated selection):
    Code (CSharp):
    1.         Selection.objects = selected;
     
  8. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    920
    Thanks for the snippet!

    May I ask if anyone ever released this on GitHub and is still mantaining it?

    @TTTTTa , can you remember the source, to properly crediting Baste? Thank you :)

    Years later the "feature" is still there, by design.
    EDIT: it IS like this officially by design! https://issuetracker.unity3d.com/is...ompletely-break-a-link-to-the-original-prefab

    I wonder why they left this "emergency recover" way to reconnect to a prefab. Probably it shouldn't be called "Break" but "Isolate" since you're only freezing the bound. And then we should also have a way to actually break the connection without using hacks.

    I'm curious to see what's going to happen when all this goes "nested" :D
     
    Harinezumi likes this.
  9. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,719
    Harinezumi and NeatWolf like this.
  10. genericxs

    genericxs

    Joined:
    Apr 19, 2018
    Posts:
    1
    This works like a charm, thanks!
     
  11. Tony-Lovell

    Tony-Lovell

    Joined:
    Jul 14, 2014
    Posts:
    120
    re: "Break the prefab instance on the gameObject" ... HOW, in 2020.1.f1? Where is this option located?

    tone
     
unityunity