Files
trail-into-darkness/Packages/com.jovian.inspector/Editor/Attributes/AssetDropdownAttribute.cs
2026-03-29 18:59:24 +02:00

89 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Jovian.Utilities;
using UnityEngine;
using Object = UnityEngine.Object;
namespace InspectorToolkit
{
/// <summary>
/// Finds all objects in the project matching <c>filter</c> string and lists alphabetically in a dropdown (if they are <c>assetType</c>)
/// </summary>
public class AssetDropdownAttribute : PropertyAttribute
{
public readonly Type assetType;
public readonly string filter;
public AssetDropdownAttribute(Type assetType, string filter)
{
this.assetType = assetType;
this.filter = filter;
}
}
}
#if UNITY_EDITOR
namespace InspectorToolkit.Internal
{
using UnityEditor;
[CustomPropertyDrawer(typeof(AssetDropdownAttribute))]
public class AssetDropdownAttributeDrawer : PropertyDrawer
{
private bool isInitialized;
private bool hasValidTarget;
private List<Object> objects;
private string[] values;
private int selectedIndex = -1;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (property.propertyType != SerializedPropertyType.ObjectReference)
{
Debug.LogError("Required property to be an ObjectReference.");
EditorGUI.PropertyField(position, property, label);
return;
}
if (!isInitialized)
{
Initialize();
}
EditorGUI.BeginChangeCheck();
selectedIndex = property.objectReferenceValue != null ? Array.IndexOf(values, property.objectReferenceValue.name) : -1;
selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex, values);
if (Event.current.type == EventType.MouseDown && Event.current.modifiers == EventModifiers.Shift &&
GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
{
isInitialized = false;
}
if (EditorGUI.EndChangeCheck())
{
property.objectReferenceValue = objects[selectedIndex];
property.serializedObject.ApplyModifiedProperties();
}
}
private void Initialize()
{
AssetDropdownAttribute assetDropdownAttribute = (AssetDropdownAttribute)attribute;
objects = AssetUtility.FindAllObjectsInProject(assetDropdownAttribute.assetType, assetDropdownAttribute.filter);
objects.Sort(SortByName);
values = objects.Select(obj => obj.name).ToArray();
isInitialized = true;
}
private static int SortByName(Object a, Object b) {
return string.Compare(a.name, b.name, StringComparison.Ordinal);
}
}
}
#endif