Search Issue Tracker

By Design

Votes

0

Found in

2019.2

2019.3.3f1

2020.2

Issue ID

1225065

Regression

No

Prefabs which are not nested return null value when using PrefabUtility.GetOutermostPrefabInstanceRoot()

Scripting

-

Steps to reproduce:
1. Download and open attached "BetterUI_Test2019" project
2. Open "Betterizer" script
3. Insert a breakpoint in line 272
4. Press "Attach to Unity" in the toolbar
5. Open the "Prefab" prefab in the Unity Engine
6. In the Inspector window, right-click on the "Image" component and press "Make Better"
7. Open the Visual Studio window

Expected outcome: "prefabRoot" in the Autos window does not have a null value
Actual outcome: "prefabRoot" in the Autos window has a null value

Reproducible with: 2019.2.21f1, 2019.3.4f1, 2020.1.0b1, 2020.2.0a2
Could not test with: 2017.4, 2018.4 (Console errors)

  1. Resolution Note:

    Using GetOutermostPrefabInstanceRoot on a component that is not an instance will return null. When opening Prefab Mode the Prefab asset contents is loaded from the .prefab source file and the components here are no longer from an instance'. In Prefab Mode you here are allowed to make structural changes unlike prefab instances in the scene where restructuring is prohibited. So this is an important distinction: when opening Prefab it is no longer the instance with its potential overrides you are seeing but the actual prefab asset objects.

    In order for your script to support Prefab Mode I have modified the start of your script as follows:

    private static IEnumerable<NestedPrefabInfo> FindNestedPrefabReferencesTo(UnityEngine.Component obj)
    {
    string prefabPath = string.Empty;
    GameObject prefabRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(obj);
    if (prefabRoot != null)
    {
    // Handle prefab instances in the scene
    prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefabRoot);
    }
    else
    {
    // Handle Prefab Mode
    var prefabStage = PrefabStageUtility.GetPrefabStage(obj.gameObject);
    if (prefabStage != null)
    {
    prefabRoot = prefabStage.prefabContentsRoot;
    prefabPath = prefabStage.prefabAssetPath;
    }
    }

    if (prefabRoot != null)
    {
    List<HierarchyInfo> hierarchy = GetHierarchyStructure(obj.transform, prefabRoot.transform);

    // iterate all prefabs in project
    foreach (GameObject prefab in IterateAllPrefabs())
    ...

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.