You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.1 KiB
99 lines
3.1 KiB
using UnityEngine; |
|
using UnityEditor; |
|
using System.Linq; |
|
using System.Text.RegularExpressions; |
|
using System; |
|
|
|
namespace NaughtyAttributes.Editor |
|
{ |
|
[CustomPropertyDrawer(typeof(SceneAttribute))] |
|
public class ScenePropertyDrawer : PropertyDrawerBase |
|
{ |
|
private const string SceneListItem = "{0} ({1})"; |
|
private const string ScenePattern = @".+\/(.+)\.unity"; |
|
private const string TypeWarningMessage = "{0} must be an int or a string"; |
|
private const string BuildSettingsWarningMessage = "No scenes in the build settings"; |
|
|
|
protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label) |
|
{ |
|
bool validPropertyType = property.propertyType == SerializedPropertyType.String || property.propertyType == SerializedPropertyType.Integer; |
|
bool anySceneInBuildSettings = GetScenes().Length > 0; |
|
|
|
return (validPropertyType && anySceneInBuildSettings) |
|
? GetPropertyHeight(property) |
|
: GetPropertyHeight(property) + GetHelpBoxHeight(); |
|
} |
|
|
|
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) |
|
{ |
|
EditorGUI.BeginProperty(rect, label, property); |
|
|
|
string[] scenes = GetScenes(); |
|
bool anySceneInBuildSettings = scenes.Length > 0; |
|
if (!anySceneInBuildSettings) |
|
{ |
|
DrawDefaultPropertyAndHelpBox(rect, property, BuildSettingsWarningMessage, MessageType.Warning); |
|
return; |
|
} |
|
|
|
string[] sceneOptions = GetSceneOptions(scenes); |
|
switch (property.propertyType) |
|
{ |
|
case SerializedPropertyType.String: |
|
DrawPropertyForString(rect, property, label, scenes, sceneOptions); |
|
break; |
|
case SerializedPropertyType.Integer: |
|
DrawPropertyForInt(rect, property, label, sceneOptions); |
|
break; |
|
default: |
|
string message = string.Format(TypeWarningMessage, property.name); |
|
DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); |
|
break; |
|
} |
|
|
|
EditorGUI.EndProperty(); |
|
} |
|
|
|
private string[] GetScenes() |
|
{ |
|
return EditorBuildSettings.scenes |
|
.Where(scene => scene.enabled) |
|
.Select(scene => Regex.Match(scene.path, ScenePattern).Groups[1].Value) |
|
.ToArray(); |
|
} |
|
|
|
private string[] GetSceneOptions(string[] scenes) |
|
{ |
|
return scenes.Select((s, i) => string.Format(SceneListItem, s, i)).ToArray(); |
|
} |
|
|
|
private static void DrawPropertyForString(Rect rect, SerializedProperty property, GUIContent label, string[] scenes, string[] sceneOptions) |
|
{ |
|
int index = IndexOf(scenes, property.stringValue); |
|
int newIndex = EditorGUI.Popup(rect, label.text, index, sceneOptions); |
|
string newScene = scenes[newIndex]; |
|
|
|
if (!property.stringValue.Equals(newScene, StringComparison.Ordinal)) |
|
{ |
|
property.stringValue = scenes[newIndex]; |
|
} |
|
} |
|
|
|
private static void DrawPropertyForInt(Rect rect, SerializedProperty property, GUIContent label, string[] sceneOptions) |
|
{ |
|
int index = property.intValue; |
|
int newIndex = EditorGUI.Popup(rect, label.text, index, sceneOptions); |
|
|
|
if (property.intValue != newIndex) |
|
{ |
|
property.intValue = newIndex; |
|
} |
|
} |
|
|
|
private static int IndexOf(string[] scenes, string scene) |
|
{ |
|
var index = Array.IndexOf(scenes, scene); |
|
return Mathf.Clamp(index, 0, scenes.Length - 1); |
|
} |
|
} |
|
}
|
|
|