はじめに
using System.Linq; using UnityEditor; using UnityEngine; public static class Example { [MenuItem( "Tools/Hoge" )] private static void Hoge() { var go = Selection.activeGameObject; var components = go .GetComponents<Component>() .Where( c => c != null ) ; foreach ( var c in components ) { var so = new SerializedObject( c ); var sp = so.GetIterator(); while ( sp.NextVisible( true ) ) { if ( sp.propertyType != SerializedPropertyType.ObjectReference ) continue; if ( sp.objectReferenceValue != null ) continue; if ( sp.objectReferenceInstanceIDValue == 0 ) continue; Debug.Log( "Missing!" ); } } } }
以前の Unity のバージョンであれば、上記のようなエディタ拡張を作成することで
Inspector で参照が Missing になっているかどうかを確認することができたのですが、
Unity 2018.3 で同様の処理を実行したところ、
Missing の判定が検出できなくなっていました
(Missing でも None でも sp.objectReferenceInstanceIDValue が 0 になってしまう)
対処方法
sprite: {fileID: 0}
参照が None になっている時は fileID が 0 になり、
sprite: {fileID: 21300000, guid: 6bce31ca45f21bd40a5a6756299d5bfb, type: 3}
参照が Missing になっている時は fileID が設定されている状態になるので
- sp.propertyType が SerializedPropertyType.ObjectReference
- sp.objectReferenceValue が null
- fileID が 0 ではない
上記のような判定を使用することで Unity 2018.3 でも Missing References を検出できます
以下にサンプルコードを記載します
using System.Linq; using UnityEditor; using UnityEngine; public class EditTest : MonoBehaviour { [MenuItem( "Tools/Hoge" )] private static void Hoge() { var go = Selection.activeGameObject; var components = go .GetComponents<Component>() .Where( c => c != null ) ; foreach ( var c in components ) { var so = new SerializedObject( c ); var sp = so.GetIterator(); while ( sp.NextVisible( true ) ) { if ( sp.propertyType != SerializedPropertyType.ObjectReference ) continue; if ( sp.objectReferenceValue != null ) continue; if ( !sp.hasChildren ) continue; var fileId = sp.FindPropertyRelative( "m_FileID" ); if ( fileId == null ) continue; if ( fileId.intValue == 0 ) continue; Debug.Log( "Missing!" ); } } } }