Gameplay Ingredients是一组用于 Unity 游戏的运行时和编辑器工具:一组脚本的集合,可在制作游戏和原型时简化简单的任务。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

114 行
3.4 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
using UnityEditor.Experimental.UIElements;
using System;
using System.Linq;
using System.Reflection;
namespace GraphProcessor
{
public static class FieldFactory
{
static readonly Dictionary< Type, Type > fieldDrawers = new Dictionary< Type, Type >();
static readonly MethodInfo createFieldMethod = typeof(FieldFactory).GetMethod("CreateFieldSpecific", BindingFlags.Static | BindingFlags.Public);
static FieldFactory()
{
foreach (var type in AppDomain.CurrentDomain.GetAllTypes())
{
var drawerAttribute = type.GetCustomAttributes(typeof(FieldDrawerAttribute), false).FirstOrDefault() as FieldDrawerAttribute;
if (drawerAttribute == null)
continue ;
AddDrawer(drawerAttribute.fieldType, type);
}
// щ(ºДºщ) ...
AddDrawer(typeof(int), typeof(IntegerField));
AddDrawer(typeof(long), typeof(LongField));
AddDrawer(typeof(float), typeof(FloatField));
AddDrawer(typeof(double), typeof(DoubleField));
AddDrawer(typeof(string), typeof(TextField));
AddDrawer(typeof(Bounds), typeof(BoundsField));
AddDrawer(typeof(Color), typeof(ColorField));
AddDrawer(typeof(Vector2), typeof(Vector2Field));
AddDrawer(typeof(Vector3), typeof(Vector3Field));
AddDrawer(typeof(Vector4), typeof(Vector4Field));
AddDrawer(typeof(AnimationCurve), typeof(CurveField));
AddDrawer(typeof(Enum), typeof(EnumField));
AddDrawer(typeof(Gradient), typeof(GradientField));
AddDrawer(typeof(UnityEngine.Object), typeof(ObjectField));
AddDrawer(typeof(Rect), typeof(RectField));
}
static void AddDrawer(Type fieldType, Type drawerType)
{
var iNotifyType = typeof(INotifyValueChanged<>).MakeGenericType(fieldType);
if (!iNotifyType.IsAssignableFrom(drawerType))
{
Debug.LogWarning("The custom field drawer " + drawerType + " does not implements INotifyValueChanged< " + fieldType + " >");
return ;
}
fieldDrawers[fieldType] = drawerType;
}
public static INotifyValueChanged< T > CreateField< T >()
{
return CreateField(typeof(T)) as INotifyValueChanged< T >;
}
public static VisualElement CreateField(Type t)
{
Type drawerType;
fieldDrawers.TryGetValue(t, out drawerType);
if (drawerType == null)
drawerType = fieldDrawers.FirstOrDefault(kp => kp.Key.IsReallyAssignableFrom(t)).Value;
if (drawerType == null)
{
Debug.LogWarning("Can't find field drawer for type: " + t);
return null;
}
var field = Activator.CreateInstance(drawerType);
// For mutiline
if (field is TextField)
{
(field as TextField).multiline = true;
}
return field as VisualElement;
}
public static INotifyValueChanged< T > CreateFieldSpecific< T >(FieldInfo field, T value, Action< object > onValueChanged)
{
var fieldDrawer = CreateField< T >();
if (fieldDrawer == null)
return null;
fieldDrawer.value = value;
fieldDrawer.OnValueChanged((e) => {
onValueChanged(e.newValue);
});
return fieldDrawer as INotifyValueChanged< T >;
}
public static VisualElement CreateField(FieldInfo field, object value, Action< object > onValueChanged)
{
var createFieldSpecificMethod = createFieldMethod.MakeGenericMethod(field.FieldType);
return createFieldSpecificMethod.Invoke(null, new object[]{field, value, onValueChanged}) as VisualElement;
}
}
}