using System; using System.Collections.Generic; using UnityEditorInternal; using UnityEngine; using UnityEngine.Perception.GroundTruth; namespace UnityEditor.Perception.GroundTruth { [CustomEditor(typeof(PerceptionCamera))] sealed class PerceptionCameraEditor : Editor { Dictionary m_CameraLabelerDrawers = new Dictionary(); ReorderableList m_LabelersList; SerializedProperty labelersProperty => this.serializedObject.FindProperty("m_Labelers"); PerceptionCamera perceptionCamera => ((PerceptionCamera)this.target); public void OnEnable() { m_LabelersList = new ReorderableList(this.serializedObject, labelersProperty, true, false, true, true); m_LabelersList.drawHeaderCallback = (rect) => { EditorGUI.LabelField(rect, "Camera Labelers", EditorStyles.largeLabel); }; m_LabelersList.elementHeightCallback = GetElementHeight; m_LabelersList.drawElementCallback = DrawElement; m_LabelersList.onAddCallback += OnAdd; m_LabelersList.onRemoveCallback += OnRemove; } float GetElementHeight(int index) { var serializedProperty = labelersProperty; var element = serializedProperty.GetArrayElementAtIndex(index); var editor = GetCameraLabelerDrawer(element, index); return editor.GetElementHeight(element); } void DrawElement(Rect rect, int index, bool isactive, bool isfocused) { var element = labelersProperty.GetArrayElementAtIndex(index); var editor = GetCameraLabelerDrawer(element, index); editor.OnGUI(rect, element); } void OnRemove(ReorderableList list) { labelersProperty.DeleteArrayElementAtIndex(list.index); serializedObject.ApplyModifiedProperties(); } void OnAdd(ReorderableList list) { Undo.RegisterCompleteObjectUndo(target, "Remove camera labeler"); var labelers = labelersProperty; var dropdownOptions = TypeCache.GetTypesDerivedFrom(); var menu = new GenericMenu(); foreach (var option in dropdownOptions) { var localOption = option; menu.AddItem(new GUIContent(option.Name), false, () => AddLabeler(localOption)); } menu.ShowAsContext(); } void AddLabeler(Type labelerType) { var labeler = (CameraLabeler)Activator.CreateInstance(labelerType); labeler.enabled = true; perceptionCamera.AddLabeler(labeler); serializedObject.ApplyModifiedProperties(); } public override void OnInspectorGUI() { EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(perceptionCamera.description))); EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(perceptionCamera.period))); EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(perceptionCamera.startTime))); EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(perceptionCamera.captureRgbImages))); //EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(PerceptionCamera.labelers))); m_LabelersList.DoLayoutList(); if (EditorSettings.asyncShaderCompilation) { EditorGUILayout.HelpBox("Asynchronous shader compilation may result in invalid data in beginning frames. This can be disabled in Project Settings -> Edtior -> Asynchronous Shader Compilation", MessageType.Warning); } } CameraLabelerDrawer GetCameraLabelerDrawer(SerializedProperty element, int listIndex) { CameraLabelerDrawer drawer; if (m_CameraLabelerDrawers.TryGetValue(element, out drawer)) return drawer; var labeler = perceptionCamera.labelers[listIndex]; foreach (var drawerType in TypeCache.GetTypesWithAttribute(typeof(CameraLabelerDrawerAttribute))) { var attr = (CameraLabelerDrawerAttribute)drawerType.GetCustomAttributes(typeof(CameraLabelerDrawerAttribute), true)[0]; if (attr.targetLabelerType == labeler.GetType()) { drawer = (CameraLabelerDrawer)Activator.CreateInstance(drawerType); drawer.cameraLabeler = labeler; break; } if (attr.targetLabelerType.IsAssignableFrom(labeler.GetType())) { drawer = (CameraLabelerDrawer)Activator.CreateInstance(drawerType); drawer.cameraLabeler = labeler; } } m_CameraLabelerDrawers[element] = drawer; return drawer; } } }