Search Issue Tracker
By Design
By Design in 2023.2.X
Votes
0
Found in
2020.3.45f1
2021.3.18f1
2022.2.7f1
2023.1.0b4
2023.2.0a2
Issue ID
UUM-27296
Regression
No
PrefabUtility.IsPartOfVariantPrefab() doesn't recognize variants when a Prefab Variant is inside a non-Variant Prefab
How to reproduce:
- Open the attached project "IsPartOfVariantPrefab.zip"
- Select and drag Assets/3 (1).prefab into the Hierarchy window
Expected results: "6: VARIANT" is shown in the Console window
Actual results: "6: NON VARIANT" is shown in the Console window
Reproducible with: 2020.3.45f1, 2021.3.18f1, 2022.2.7f1, 2023.1.0b4, 2023.2.0a2
Reproducible on: Windows 10
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
- Texture2D hash changes inside of an AssetBundle when rebuilding a SpriteAtlas bundle with an empty AssetPostprocessor Script enabled
- Aniso Level still applies when Generate MipMap is disabled in Texture Import Settings
- Mipmap Limit Groups long names are not truncated when creating a new Mipmap Limit Group with a long name
- “ArgumentException: Invalid double parameter.” error is thrown when Infinity is typed into the Fixed Timestep field
- GameObject becomes gray when using HDRP and STP together on macOS
Resolution Note:
Objects that are part of a Prefab can either be part of a regular Prefab or a Prefab Variant, not both. Which type of Prefab they are part of, depends on their outermost Prefab Instance root (https://docs.unity3d.com/ScriptReference/PrefabUtility.GetOutermostPrefabInstanceRoot.html). When a Prefab Variant is nested inside a regular Prefab, the outermost Prefab Instance is a regular prefab, which is why the API call returns false. This was indeed unclear in the documentation, which is why we will update this to clarify it.
To find out if a given object is part of a Variant Prefab at any point in the nesting chain, you can use the following script:
[ExecuteInEditMode]
public class PrefabVariantTest : MonoBehaviour
{
private void Start()
{
bool isPartOfVariant = false;
Object obj = this;
while (obj)
{
if (PrefabUtility.IsPartOfVariantPrefab(obj))
{
isPartOfVariant = true;
break;
}
obj = PrefabUtility.GetCorrespondingObjectFromSource(obj);
}
if (isPartOfVariant)
{
Debug.Log($"{gameObject.name}: VARIANT");
}
else
{
Debug.Log($"{gameObject.name}: NON VARIANT");
}
}
}
Resolution Note (2023.2.X):
Objects that are part of a Prefab can either be part of a regular Prefab or a Prefab Variant, not both. Which type of Prefab they are part of, depends on their outermost Prefab Instance root (https://docs.unity3d.com/ScriptReference/PrefabUtility.GetOutermostPrefabInstanceRoot.html). When a Prefab Variant is nested inside a regular Prefab, the outermost Prefab Instance is a regular prefab, which is why the API call returns false. This was indeed unclear in the documentation, which is why we will update this to clarify it.
To find out if a given object is part of a Variant Prefab at any point in the nesting chain, you can use the following script:
[ExecuteInEditMode]
public class PrefabVariantTest : MonoBehaviour
{
private void Start()
{
bool isPartOfVariant = false;
Object obj = this;
while (obj)
{
if (PrefabUtility.IsPartOfVariantPrefab(obj))
{
isPartOfVariant = true;
break;
}
obj = PrefabUtility.GetCorrespondingObjectFromSource(obj);
}
if (isPartOfVariant)
{
Debug.Log($"{gameObject.name}: VARIANT");
}
else
{
Debug.Log($"{gameObject.name}: NON VARIANT");
}
}
}