You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Plugins/NaughtyAttributes/Scripts/Editor/PropertyDrawers/ScenePropertyDrawer.cs

100 lines
3.1 KiB
C#

1 month ago
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);
}
}
}