BITFALL/Assets/BITKit/Unity/Scripts/Events/UnityEvent.cs

142 lines
3.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.UIElements;
#if UNITY_EDITOR
using Cysharp.Threading.Tasks;
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace BITKit.Events
{
[Serializable]
public class UnityEventData
{
public Object Target;
public string MethodName;
}
[Serializable]
public class UnityEvent
{
public List<UnityEventData> Targets = new List<UnityEventData>();
public void Invoke(params object[] objects)
{
foreach (var x in Targets)
{
x.Target.GetType().GetMethod(x.MethodName)?.Invoke(x.Target,objects);
}
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(UnityEvent))]
public class UnityEventDataPropertyDrawer:PropertyDrawer
{
private VisualElement root;
private UnityEvent agent;
private SerializedProperty _property;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
_property = property;
agent = property.Get<UnityEvent>();
root = new VisualElement
{
style =
{
paddingLeft = 10,
paddingTop = 10,
paddingRight = 10,
paddingBottom = 10,
}
};
root.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
Update();
return root;
}
private void Update()
{
root.Clear();
var targets = _property.FindPropertyRelative(nameof(UnityEvent.Targets));
_property.serializedObject.Update();
var label = root.Create<Label>();
label.text = _property.displayName;
var flex = root.Create<VisualElement>();
flex.style.flexDirection = FlexDirection.Row;
var containers = new[] { flex.Create<VisualElement>(), flex.Create<VisualElement>(),flex.Create<VisualElement>() };
containers[1].style.flexGrow = 1;
for (var i = 0; i < targets.arraySize; i++)
{
var x = agent.Targets[i];
var objectField = containers[0].Create<ObjectField>();
var field = containers[1].Create<DropdownField>();
var removeButton = containers[2].Create<Button>();
var data = targets.GetArrayElementAtIndex(i);
var target = data.FindPropertyRelative(nameof(UnityEventData.Target));
objectField.BindProperty(target);
if (x.Target is not null)
{
field.choices = x.Target.GetType().GetMethods().Select(x => x.Name).ToList();
}
field.value = x.MethodName;
field.RegisterValueChangedCallback(changeEvent =>
{
x.MethodName = changeEvent.newValue;
});
field.style.flexGrow = 1;
removeButton.text = "X";
removeButton.clicked+=()=>{
agent.Targets.Remove(x);
Update();
};
}
var addButton = root.Create<Button>();
addButton.text = "Add";
addButton.clicked += () =>
{
agent.Targets.Add(new());
Update();
};
var invokeButton = root.Create<Button>();
invokeButton.text = "Invoke";
invokeButton.clicked +=()=> agent.Invoke();
}
}
#endif
}