Search Issue Tracker
By Design
Votes
0
Found in
2020.3
2020.3.12f1
Issue ID
1358996
Regression
No
Unexpected null references during prefab import after upgrading a project from 2019.4 to 2020.3
Reproduction steps:
1. Open the attached "Project" project
2. Observe the Console
Expected result: No BUILD SYSTEM NULL POINTER errors and the Scene view isn't gray
Actual result: Many BUILD SYSTEM NULL POINTER errors and the Scene view is gray
Reproducible with: 2020.3.23f1
Could not test with: 2019.4.32f1 (reproduction project is already upgraded to 2020.3, downgrading causes other errors but the Scene view remains gray), 2021.2.3f1 (other errors but the Scene view remains gray), 2022.1.0a16 (other errors, often crashes when selecting an asset/object/action, the Scene view remains gray)
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
- Articulation Body with 'Revolute' Joint Type has erratic behavior when Upper Limit is set to above 360
- WebGL Player fails to render Scene when Terrain with Detail Mesh is added and WebGPU Graphics API is used
- Inconsistent errors are logged when different types are passed into the Query "Q<>" method in UIToolkit and the ancestor VisualElement is null
- Crash on GetMaterialPropertyByIndex when opening a specific Scene
- Discrepancies in the styling are present when using a TSS file instead of a USS file in custom EditorWindow
Resolution Note:
Non dependent Prefabs (Prefabs that are not nested nor Variants) are imported in a nondeterministic order. In this case OnValidate is called while a Prefab is imported and it checks if a Prefab that is referenced by a script from the current Prefab is non null, which depending on the importing order might hold or not.
To check if a script referenced Prefab is valid we have https://docs.unity3d.com/2022.1/Documentation/ScriptReference/AssetPostprocessor.OnPostprocessAllAssets.html which gets called after all Prefabs are imported.
Following is an example of a similar validation:
ItemBlueprint.cs:
using System.Collections.Generic;
using UnityEngine;
public class ItemBlueprint : MonoBehaviour
{
public List<GameObject> referencedPrefabs = new List<GameObject>();
public void ValidateReferencedPrefabs(string caller)
{
foreach(var referencedPrefab in referencedPrefabs)
{
if(referencedPrefab == null)
{
Debug.LogError(caller + ": - Referenced prefab is null");
}
}
}
public void OnValidate()
{
ValidateReferencedPrefabs("OnValidate");
}
}
PrefabValidator.cs:
using UnityEditor;
using UnityEngine;
public class PrefabValidator : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach(var importedAsset in importedAssets)
{
if(importedAsset.EndsWith(".prefab", System.StringComparison.OrdinalIgnoreCase))
{
var prefabRoot = AssetDatabase.LoadMainAssetAtPath(importedAsset) as GameObject;
var itemBlueprints = prefabRoot.GetComponentsInChildren<ItemBlueprint>();
foreach(var itemBlueprint in itemBlueprints)
{
itemBlueprint.ValidateReferencedPrefabs("OnPostprocessAllAssets");
}
}
}
}
}
In this case the calls to ValidateReferencedPrefabs from OnPostprocessAllAssets will log errors only for missing referenced Prefabs and the calls from OnValidate will log errors for all missing referenced Prefabs and for non missing referenced Prefabs at random.
Please note that this approach won't validate Prefabs that are already imported - they are not in string[] importedAssets. This also applies to OnValidate - if a referenced Prefab gets deleted OnValidate won't be called on the Prefab that references the deleted Prefab until it gets loaded (it's selected, imported, etc)