Array や List の場合は要素のTypeを取得する必要があるためチェック処理を入れている
また、System系の構造体やクラスだと無限ループすることがあったので Array や List 以外の System系は無視している
※Array や List の Path には非対応
private static Dictionary<string, FieldInfo> GetAllFields(Type type, BindingFlags flags) { Dictionary<string, FieldInfo> list = new Dictionary<string, FieldInfo>(); GetAllFieldsRecursive(type, flags, string.Empty, ref list); return list; } private static void GetAllFieldsRecursive( Type type, BindingFlags flags, string path, ref Dictionary<string, FieldInfo> list) { foreach (var field in type.GetFields(flags)) { var key = string.IsNullOrEmpty(path) ? field.Name : $"{path}{field.Name}"; if (!list.ContainsKey(key)) list.Add(key, field); var ftype = field.FieldType; if (ftype.Namespace != null && (ftype.Namespace.StartsWith("System.") && !ftype.IsArray && !(ftype.IsGenericType && (ftype.GetGenericTypeDefinition() == typeof(List<>) || ))) ) { continue; } if (ftype.IsClass && ftype != typeof(string) && ftype.IsSerializable) { if (ftype.IsArray) ftype = ftype.GetElementType(); else if ( ftype.IsGenericType && (ftype.GetGenericTypeDefinition() == typeof(List<>) || ftype.GetGenericTypeDefinition() == typeof(IList<>)) ) ftype = ftype.GetGenericArguments()[0]; GetAllFieldsRecursive(ftype, flags, $"{field.Name}.", ref list); } } }
serializedObject.FindProperty で子フィールドを取得するときは ”.” を利用するので、結合している
結果以下のように取得できる
再帰的に FiledInfo が欲しいだけなら Dictionary じゃなくて FieldInfo に変更すればよい