// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using UnityEditor; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Editor { /// /// Creates a custom picker based on the list of scene in the build settings. /// /// /// /// [ScenePick] /// public int SceneId; /// /// [CustomPropertyDrawer(typeof(ScenePickAttribute))] public class ScenePickPropertyDrawer : PropertyDrawer { /// /// List of Options extracted from the Editor /// private static GUIContent[] Options; /// /// List of Scene GUIDS for the scenes /// private static string[] PropertyData; /// /// Select this option to remove the event string /// private static readonly string UnselectedText = "-- None --"; /// /// Text to display when an entry is missing /// private static readonly string MissingText = "-- Missing --"; /// /// Function called by unity to draw the GUI for this property /// We are replacing the int value of the backing field with a dropdown list of scene names /// /// See base class /// See base class /// See base class public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { BuildOptions(); var currentGuid = property.stringValue.Split(';')[0]; var currentId = System.Array.FindIndex(PropertyData, (x) => x.Contains(currentGuid)); if (currentId == -1) { // Not found, display the missing text currentId = Options.Length - 1; } else if (currentId > 0 && property.stringValue != PropertyData[currentId]) { // If the string has changed, update the property. // This will happen if the scene is renamed. property.stringValue = PropertyData[currentId]; EditorUtility.SetDirty(property.serializedObject.targetObject); } EditorGUI.BeginProperty(position, new GUIContent(property.name), property); var newId = EditorGUI.Popup(position, label, currentId, Options); if (newId != currentId) { property.stringValue = PropertyData[newId]; EditorUtility.SetDirty(property.serializedObject.targetObject); } EditorGUI.EndProperty(); } /// /// Build the list of scene names /// Note: Scene 0 is the no-scene option. /// private static void BuildOptions() { var scenes = EditorBuildSettings.scenes; if (scenes.Length > 0) { Options = new GUIContent[scenes.Length + 2]; PropertyData = new string[scenes.Length + 2]; Options[0] = new GUIContent(UnselectedText); PropertyData[0] = string.Empty; for (int i = 0; i < scenes.Length; i++) { // Right, replace '/' with '\' otherwise the list displays like a menu where '/' denotes a sub-menu. Options[i + 1] = new GUIContent(scenes[i].path.Replace("/", "\\")); PropertyData[i + 1] = scenes[i].guid.ToString() + ";" + scenes[i].path; } Options[scenes.Length + 1] = new GUIContent(MissingText); PropertyData[scenes.Length + 1] = MissingText; } else { Options = new GUIContent[2]; PropertyData = new string[2]; Options[0] = new GUIContent(UnselectedText); PropertyData[0] = string.Empty; Options[1] = new GUIContent(MissingText); PropertyData[1] = MissingText; } } } }