120 lines
4.2 KiB
C#
120 lines
4.2 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Editor
|
|
{
|
|
/// <summary>
|
|
/// Creates a custom picker based on the list of scene in the build settings.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <code>
|
|
/// [ScenePick]
|
|
/// public int SceneId;
|
|
/// </code>
|
|
/// </example>
|
|
[CustomPropertyDrawer(typeof(ScenePickAttribute))]
|
|
public class ScenePickPropertyDrawer : PropertyDrawer
|
|
{
|
|
/// <summary>
|
|
/// List of Options extracted from the Editor
|
|
/// </summary>
|
|
private static GUIContent[] Options;
|
|
|
|
/// <summary>
|
|
/// List of Scene GUIDS for the scenes
|
|
/// </summary>
|
|
private static string[] PropertyData;
|
|
|
|
/// <summary>
|
|
/// Select this option to remove the event string
|
|
/// </summary>
|
|
private static readonly string UnselectedText = "-- None --";
|
|
|
|
/// <summary>
|
|
/// Text to display when an entry is missing
|
|
/// </summary>
|
|
private static readonly string MissingText = "-- Missing --";
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="position">See base class</param>
|
|
/// <param name="property">See base class</param>
|
|
/// <param name="label">See base class</param>
|
|
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();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Build the list of scene names
|
|
/// Note: Scene 0 is the no-scene option.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} |