/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; namespace Oculus.Interaction.Editor { public class SimplifiedEditor : UnityEditor.Editor { protected EditorBase _editorDrawer; private const string OptionalSection = "Optionals"; protected virtual void OnEnable() { _editorDrawer = new EditorBase(serializedObject); Dictionary sections = FindCustomSections(serializedObject); foreach (var sectionData in sections) { RegisterSection(sectionData.Key, sectionData.Value); } RegisterSection(OptionalSection, FindOptionals(serializedObject)); } protected virtual void OnDisable() { } public override void OnInspectorGUI() { _editorDrawer.DrawFullInspector(); } private void RegisterSection(string sectionName, string[] sectionProperties) { string foldoutKey = $"{GetType().FullName}.{sectionName}.Foldout"; _editorDrawer.CreateSection(sectionName, true, foldoutKey); _editorDrawer.AddToSection(sectionName, sectionProperties); } private static string[] FindOptionals(SerializedObject serializedObject) { List> props = new List>(); UnityEngine.Object obj = serializedObject.targetObject; if (obj != null) { FindAttributedSerializedFields(obj.GetType(), props); } return props.Where(p => (p.attribute.Flags & OptionalAttribute.Flag.DontHide) == 0) .Select(p => p.propertyName) .ToArray(); } private static Dictionary FindCustomSections(SerializedObject serializedObject) { List> props = new List>(); UnityEngine.Object obj = serializedObject.targetObject; if (obj != null) { FindAttributedSerializedFields(obj.GetType(), props); } Dictionary sections = new Dictionary(); var namedSections = props.GroupBy(p => p.attribute.SectionName); foreach (var namedSection in namedSections) { string[] values = namedSection.Select(p => p.propertyName).ToArray(); sections.Add(namedSection.Key, values); } return sections; } private static void FindAttributedSerializedFields(Type type, List> props) where TAttribute : PropertyAttribute { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); foreach (FieldInfo field in fields) { TAttribute attribute = field.GetCustomAttribute(); if (attribute == null) { continue; } if (field.GetCustomAttribute() == null) { continue; } props.Add(new AttributedProperty(field.Name, attribute)); } if (typeof(Component).IsAssignableFrom(type.BaseType)) { FindAttributedSerializedFields(type.BaseType, props); } } private struct AttributedProperty where TAttribute : PropertyAttribute { public string propertyName; public TAttribute attribute; public AttributedProperty(string propertyName, TAttribute attribute) { this.propertyName = propertyName; this.attribute = attribute; } } } }