313 lines
12 KiB
C#
313 lines
12 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using System.Reflection;
|
|
using System;
|
|
#if UNITY_EDITOR
|
|
using MackySoft.SerializeReferenceExtensions.Editor;
|
|
using UnityEditor;
|
|
using Editor = UnityEditor.Editor;
|
|
using UnityEditor.UIElements;
|
|
#endif
|
|
namespace BITKit
|
|
{
|
|
public class BITAttribute : System.Attribute
|
|
{
|
|
|
|
}
|
|
#if UNITY_EDITOR
|
|
[CanEditMultipleObjects]
|
|
[CustomEditor(typeof(MonoBehaviour),true)]
|
|
public class MonoBehaviorInspector : BITInspector<MonoBehaviour>
|
|
{
|
|
|
|
}
|
|
[CanEditMultipleObjects]
|
|
[CustomEditor(typeof(ScriptableObject),true)]
|
|
public class ScriptableObjectInspector : BITInspector<ScriptableObject>
|
|
{
|
|
|
|
}
|
|
[CustomPropertyDrawer(typeof(ReadOnlyAttribute),true)]
|
|
public class ReadOnlyDrawer : PropertyDrawer
|
|
{
|
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
|
{
|
|
var field = new PropertyField(property)
|
|
{
|
|
name = "PropertyField:" + property.propertyPath
|
|
};
|
|
Debug.Log("ReadOnlyAttribute");
|
|
field.pickingMode = PickingMode.Ignore;
|
|
field.SetEnabled(false);
|
|
field.style.opacity = 1;
|
|
var x = field.Q("unity-text-input");
|
|
var clearColor = new Color(0, 0, 0, 0);
|
|
x.style.backgroundColor = clearColor;
|
|
x.style.borderTopColor = clearColor;
|
|
x.style.borderBottomColor = clearColor;
|
|
x.style.borderLeftColor = clearColor;
|
|
x.style.borderRightColor = clearColor;
|
|
foreach (var visualElement in field.Children())
|
|
{
|
|
visualElement.pickingMode = PickingMode.Ignore;
|
|
}
|
|
field.Bind(property.serializedObject);
|
|
return field;
|
|
}
|
|
}
|
|
#endif
|
|
public class BITEditorUtils
|
|
{
|
|
public const string InspectorPath = "Assets/BITKit/Unity/UX/BITInspector.uss";
|
|
public const string StylePath = "Assets/BITKit/Unity/UX/Common/Common.uss";
|
|
#if UNITY_EDITOR
|
|
public static StyleSheet Style => AssetDatabase.LoadAssetAtPath<StyleSheet>(StylePath);
|
|
public static StyleSheet InspectorStyleSheet => AssetDatabase.LoadAssetAtPath<StyleSheet>(InspectorPath);
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public static class BITInspectorExtensions
|
|
{
|
|
public static T Get<T>(this SerializedProperty self)
|
|
{
|
|
var obj = self.serializedObject.targetObject;
|
|
var type = obj.GetType();
|
|
var field = type.GetField(self.propertyPath, ReflectionHelper.Flags);
|
|
if (field is null)
|
|
{
|
|
throw new NullReferenceException($"Field {self.propertyPath} is null");
|
|
}
|
|
return (T)field.GetValue(obj);
|
|
}
|
|
public static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, bool hideScript)
|
|
{
|
|
container.Clear();
|
|
if (serializedObject.targetObject is null)
|
|
{
|
|
var label = container.Create<Label>();
|
|
label.text = "Null";
|
|
return;
|
|
}
|
|
var property = serializedObject.GetIterator();
|
|
|
|
if (!property.NextVisible(true)) return; // Expand first child.
|
|
do
|
|
{
|
|
if (property.propertyPath == "m_Script" && hideScript)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var type = serializedObject.targetObject.GetType();
|
|
var fieldInfo = serializedObject.targetObject.GetType().GetField(property.propertyPath, ReflectionHelper.Flags);
|
|
// if (fieldInfo is not null && type == typeof(string) && Attribute.IsDefined(fieldInfo, typeof(ReadOnlyAttribute),true))
|
|
// {
|
|
// var attribute = fieldInfo.GetCustomAttribute<ReadOnlyAttribute>();
|
|
// var _container = container.Create<VisualElement>();
|
|
// _container.style.flexDirection = FlexDirection.Row;
|
|
//
|
|
// if (attribute.HideLabel is false)
|
|
// {
|
|
// _container.Create<Label>().text = $"{property.displayName}:";
|
|
// _container.Create<VisualElement>().style.flexGrow = 1;
|
|
// }
|
|
// _container.Create<Label>().bindingPath = property.propertyPath;
|
|
// }
|
|
// else
|
|
// if (PropertyDrawerCache.TryGetPropertyDrawer(type, out var drawer))
|
|
// {
|
|
// var ve = drawer.CreatePropertyGUI(property);
|
|
// container.Add(ve);
|
|
// }
|
|
// else
|
|
{
|
|
//var label = container.Create<Label>();
|
|
//label.text =$"propertyPath:{property.propertyPath} fieldInfo:{fieldInfo} type:{type} fieldInfo:{fieldInfo}";
|
|
|
|
var field = new PropertyField(property)
|
|
{
|
|
name = "PropertyField:" + property.propertyPath
|
|
};
|
|
if (fieldInfo is not null && Attribute.IsDefined(fieldInfo, typeof(ReadOnlyAttribute), true))
|
|
{
|
|
var attribute = fieldInfo.GetCustomAttribute<ReadOnlyAttribute>();
|
|
field.pickingMode = PickingMode.Ignore;
|
|
field.SetEnabled(false);
|
|
field.style.opacity = 1;
|
|
field.AddToClassList("readonly");
|
|
if (attribute.HideLabel)
|
|
{
|
|
field.AddToClassList("hide-label");
|
|
}
|
|
}
|
|
|
|
|
|
if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
|
|
{
|
|
field.SetEnabled(false);
|
|
}
|
|
|
|
// if (fieldInfo?.FieldType == typeof(Texture2D) && fieldInfo.GetValue(serializedObject) is Texture2D texture && texture)
|
|
// {
|
|
// _container = container.Create<VisualElement>();
|
|
//
|
|
// var foldout = _container.Create<Foldout>();
|
|
// foldout.text = property.displayName;
|
|
//
|
|
// var icon = foldout.Create<VisualElement>();
|
|
// var slider = foldout.Create<Slider>();
|
|
//
|
|
// var width = 128;
|
|
// var m = texture.height /width;
|
|
//
|
|
// icon.style.width = width;
|
|
// icon.style.height = width*m;
|
|
// icon.style.backgroundImage = texture;
|
|
//
|
|
// field.style.flexGrow = 1;
|
|
//
|
|
// _container.style.backgroundColor =new StyleColor(new Color32(31,31,31,255)) ;
|
|
// _container.style.borderBottomLeftRadius = 5;
|
|
// _container.style.borderBottomRightRadius = 5;
|
|
// _container.style.borderTopLeftRadius = 5;
|
|
// _container.style.borderTopRightRadius = 5;
|
|
//
|
|
// slider.label = "Scale";
|
|
// slider.lowValue = 1;
|
|
// slider.highValue = 2;
|
|
// slider.RegisterValueChangedCallback(x =>
|
|
// {
|
|
// icon.style.width = width * x.newValue;
|
|
// icon.style.height = width*m * x.newValue;
|
|
// });
|
|
// }
|
|
|
|
container.Add(field);
|
|
}
|
|
// try
|
|
// {
|
|
// var header = type?.GetCustomAttribute<HeaderAttribute>();
|
|
// if (header != null)
|
|
// {
|
|
// var label = new Label(header.header);
|
|
// label.AddToClassList("subTitle");
|
|
// container.Add(label);
|
|
// }
|
|
// }
|
|
// catch (System.Exception e)
|
|
// {
|
|
// Debug.LogException(e);
|
|
// }
|
|
} while (property.NextVisible(false));
|
|
|
|
foreach (var method in serializedObject.targetObject.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
|
{
|
|
if (method.GetCustomAttribute<BITAttribute>() is null&& method.GetCustomAttribute<ContextMenu>() is null) continue;
|
|
if (method.GetParameters().Length is not 0) continue;
|
|
var button = new Button(() =>
|
|
{
|
|
method.Invoke(serializedObject.targetObject, null);
|
|
})
|
|
{
|
|
text = method.Name
|
|
};
|
|
|
|
container.Add(button);
|
|
}
|
|
}
|
|
}
|
|
public class BITInspector<T> : Editor
|
|
{
|
|
private const string ussName = "BITInspector";
|
|
public class VisualElementCreator
|
|
{
|
|
public static implicit operator VisualElement(VisualElementCreator self)
|
|
{
|
|
return self.root;
|
|
}
|
|
public VisualElement root;
|
|
public VE Create<VE>() where VE : VisualElement, new()
|
|
{
|
|
root = root ?? new();
|
|
var ve = new VE();
|
|
root.Add(ve);
|
|
return ve;
|
|
}
|
|
}
|
|
protected VisualElementCreator root = new();
|
|
protected T agent;
|
|
|
|
public override VisualElement CreateInspectorGUI()
|
|
{
|
|
try
|
|
{
|
|
FillDefaultInspector();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
return base.CreateInspectorGUI();
|
|
}
|
|
return root;
|
|
}
|
|
|
|
protected Label CreateSubTitle(string value)
|
|
{
|
|
var label = root.Create<Label>();
|
|
label.text = value;
|
|
label.AddToClassList("subTitle");
|
|
return label;
|
|
}
|
|
void Awake()
|
|
{
|
|
root.root = new();
|
|
|
|
if (serializedObject.targetObject is T value)
|
|
{
|
|
agent = value;
|
|
}
|
|
}
|
|
protected virtual void OnAwake(){}
|
|
void OnEnable()
|
|
{
|
|
//StyleSheet css = Addressables.LoadAssetAsync<StyleSheet>(ussName).WaitForCompletion();
|
|
StyleSheet css = AssetDatabase.LoadAssetAtPath<StyleSheet>(BITEditorUtils.InspectorPath);
|
|
|
|
root.root.styleSheets.Add(css);
|
|
|
|
EditorApplication.update += OnUpdate;
|
|
|
|
OnEnabled();
|
|
}
|
|
protected virtual void OnEnabled(){}
|
|
void OnDisable()
|
|
{
|
|
EditorApplication.update -= OnUpdate;
|
|
|
|
OnDisabled();
|
|
}
|
|
protected virtual void OnDisabled(){}
|
|
protected virtual void OnUpdate()
|
|
{
|
|
|
|
}
|
|
|
|
protected void FillDefaultInspector()
|
|
{
|
|
root.root.Clear();
|
|
BITInspectorExtensions.FillDefaultInspector(root, serializedObject, true);
|
|
}
|
|
}
|
|
public class BITProperty : PropertyDrawer
|
|
{
|
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
|
{
|
|
PropertyField propertyField = new(property);
|
|
return propertyField;
|
|
}
|
|
}
|
|
#endif
|
|
} |