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()
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)
Add comment
All about bugs
View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.
Latest issues
- VFX Graph link contrasts fail WCAG guidelines
- D3D12 PSO disk cache feature crashes if paths contain non-ASCII characters
- Different colors are present when Alpha channel is unclamped
- Visual Effects Forums link leads to generic Unity Forums
- The dithering node returns a blocky effect when the Render Scale is set to some values below 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())
...