Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to exclude from prefabs objects with a specific component type?

Discussion in 'Prefabs' started by Aka_ToolBuddy, May 1, 2021.

  1. Aka_ToolBuddy

    Aka_ToolBuddy

    Joined:
    Feb 25, 2014
    Posts:
    536
    Hi

    The problem:
    I have a GameObject, GeneratorGO, having a component of type GeneratorT
    GeneratorT generates GameObjects, OutputGO, having components of type OutputT.
    All OutputGO are children of GeneratorGO.
    My goal is to be able to make GeneratorGO part of a prefab but to automatically exclude all the OutputGOs.

    What I tried and didn't work:
    I tried finding some callback that is called everytime a prefab is saved, so I can modify the prefab when saved. Something similar to EditorSceneManager.sceneSaving. Could'nt find one

    I tried setting the hideFlags of the OutputGO to DontSaveInEditor. That works, but that means that Global Illumination will ignore all meshes part of OutputGOs. That's a deal breaker for me.

    I tried implementing ISerializationCallbackReceiver.OnBeforeSerialize() in GeneratorT, and make it delete all OutputGOs. That does not work because the inspector serializes GeneratorT. This means that all OutputGOs get deleted when I open the GeneratorT inspector.

    Any help is welcome
    Thanks
     
  2. Aka_ToolBuddy

    Aka_ToolBuddy

    Joined:
    Feb 25, 2014
    Posts:
    536
    Since my original post, I discovered PrefabUtility.prefabInstanceUpdated. Unfortunately, I am still struggling making things work properly. Here is what I did:

    Code (CSharp):
    1.  
    2. PrefabUtility.prefabInstanceUpdated += instance =>
    3. {
    4.     string prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(instance.gameObject);
    5.  
    6.     Scene previewScene = EditorSceneManager.NewPreviewScene();
    7.  
    8.     //This method is supposed to return the root, as stated in its documentation. It returns void.
    9.     PrefabUtility.LoadPrefabContentsIntoPreviewScene(prefabPath,
    10.         previewScene);
    11.     GameObject prefabContent = previewScene.GetRootGameObjects()[0];
    12.  
    13.     bool wasModified = DeleteUnwantedGameObjects();
    14.  
    15.     if (wasModified)
    16.     {
    17.         PrefabUtility.SaveAsPrefabAsset(prefabContent, prefabPath);
    18.     }
    19.  
    20.  
    21.     EditorSceneManager.ClosePreviewScene(previewScene);
    22.     AssetDatabase.SaveAssets();
    23.     AssetDatabase.Refresh();
    24. };
    25.  
    With this code the prefab is indeed updated, but the update is considered by Unity (i.e: impacted on instances of said prefab) only when I Alt+Tab twice to force Unity to check files modifications. I thought the calls to AssetDatabase that I did should flush any changes. Any help?

    Edit: The problem appears only when updating the prefab from within PrefabUtility.prefabInstanceUpdated. I couldn't solve this issue, so I had to avoid using that event.
     
    Last edited: May 9, 2021