添加unity容器类,允许使用泛型控制界面上的值。

目前添加了一次最多三个项目的属性。
This commit is contained in:
2025-07-23 20:08:59 +08:00
parent 84d79a430e
commit 49f616f4c7
63 changed files with 2580 additions and 6 deletions
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 27922b2ba2514fb58c60420c4dee6618
timeCreated: 1753252613
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 41e64720c91340eaa285a8d1a227184c
timeCreated: 1753253334
@@ -0,0 +1,89 @@
using System;
using UnityEditor;
using UnityEngine;
using XericLibrary.Runtime.MacroLibrary;
using XericUI.Core.Vessel;
using Object = UnityEngine.Object;
namespace XericUIEditor.Core.Vessel
{
[CustomPropertyDrawer(typeof(ObjectVessel<,>))]
public class ObjectVessel2Property : ObjectVesselPropertyBase
{
private Type property0Type = typeof(Object);
private Type property1Type = typeof(Object);
private string originTooltip = null;
private const float horizontalSpacing = 2f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
var targetProperty0 = property.FindPropertyRelative("target0");
var targetProperty1 = property.FindPropertyRelative("target1");
if (targetProperty0 == null || targetProperty1 == null)
{
EditorGUI.HelpBox(position, "[PROPERTY ERROR: target0/target1 not found]", MessageType.Error);
EditorGUI.EndProperty();
return;
}
Type genericType = GetActualGenericType(fieldInfo.FieldType, typeof(ObjectVessel<,>));
if (genericType != null && genericType.IsGenericType)
{
Type[] typeArgs = genericType.GetGenericArguments();
if (typeArgs.Length >= 1) property0Type = typeArgs[0];
if (typeArgs.Length >= 2) property1Type = typeArgs[1];
// 更新Tooltip
if (string.IsNullOrEmpty(originTooltip))
{
originTooltip = $"<{property0Type?.Name}, {property1Type?.Name}>\n{label.tooltip}";
label.tooltip = originTooltip;
}
}
// 布局计算(保持原有逻辑不变)
float labelWidth = EditorGUIUtility.labelWidth;
float indentOffset = EditorGUI.indentLevel * 15f;
float totalFieldWidth = position.width - labelWidth - indentOffset;
float singleFieldWidth = (totalFieldWidth - horizontalSpacing) / 2;
Rect leftFieldRect = new Rect(
position.x + labelWidth + indentOffset,
position.y,
singleFieldWidth,
EditorGUIUtility.singleLineHeight
);
Rect rightFieldRect = new Rect(
leftFieldRect.x + singleFieldWidth + horizontalSpacing,
position.y,
singleFieldWidth,
EditorGUIUtility.singleLineHeight
);
// 绘制标签和属性(保持原有逻辑不变)
EditorGUI.PrefixLabel(
new Rect(position.x + indentOffset, position.y, labelWidth, position.height),
label
);
targetProperty0.objectReferenceValue = EditorGUI.ObjectField(
leftFieldRect, GUIContent.none, targetProperty0.objectReferenceValue, property0Type, true
);
targetProperty1.objectReferenceValue = EditorGUI.ObjectField(
rightFieldRect, GUIContent.none, targetProperty1.objectReferenceValue, property1Type, true
);
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4b6688946bd24f47b4ddfe5435d4a06a
timeCreated: 1753260952
+105
View File
@@ -0,0 +1,105 @@
using System;
using UnityEditor;
using UnityEngine;
using XericLibrary.Runtime.MacroLibrary;
using XericUI.Core.Vessel;
using Object = UnityEngine.Object;
namespace XericUIEditor.Core.Vessel
{
[CustomPropertyDrawer(typeof(ObjectVessel<,,>))]
public class ObjectVessel3Property : ObjectVesselPropertyBase
{
private Type property0Type = typeof(Object);
private Type property1Type = typeof(Object);
private Type property2Type = typeof(Object);
private string originTooltip = null;
private const float horizontalSpacing = 2f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
var targetProperty0 = property.FindPropertyRelative("target0");
var targetProperty1 = property.FindPropertyRelative("target1");
var targetProperty2 = property.FindPropertyRelative("target2");
if (targetProperty0 == null || targetProperty1 == null || targetProperty2 == null)
{
EditorGUI.HelpBox(position, "[PROPERTY ERROR: target0/target1/target2 not found]", MessageType.Error);
EditorGUI.EndProperty();
return;
}
Type genericType = GetActualGenericType(fieldInfo.FieldType, typeof(ObjectVessel<,,>));
if (genericType != null && genericType.IsGenericType)
{
Type[] typeArgs = genericType.GetGenericArguments();
if (typeArgs.Length >= 1) property0Type = typeArgs[0];
if (typeArgs.Length >= 2) property1Type = typeArgs[1];
if (typeArgs.Length >= 3) property2Type = typeArgs[2];
// 更新Tooltip
if (string.IsNullOrEmpty(originTooltip))
{
originTooltip =
$"<{property0Type.Name}, {property1Type.Name}, {property2Type.Name}>\n{label.tooltip}";
label.tooltip = originTooltip;
}
}
// 布局计算(三个属性等分剩余空间)
float labelWidth = EditorGUIUtility.labelWidth;
float indentOffset = EditorGUI.indentLevel * 15f;
float totalFieldWidth = position.width - labelWidth - indentOffset;
float singleFieldWidth = (totalFieldWidth - horizontalSpacing * 2) / 3; // 三个属性,两个间距
// 计算三个属性框的位置
Rect fieldRect0 = new Rect(
position.x + labelWidth + indentOffset,
position.y,
singleFieldWidth,
EditorGUIUtility.singleLineHeight
);
Rect fieldRect1 = new Rect(
fieldRect0.x + singleFieldWidth + horizontalSpacing,
position.y,
singleFieldWidth,
EditorGUIUtility.singleLineHeight
);
Rect fieldRect2 = new Rect(
fieldRect1.x + singleFieldWidth + horizontalSpacing,
position.y,
singleFieldWidth,
EditorGUIUtility.singleLineHeight
);
// 绘制标签
EditorGUI.PrefixLabel(
new Rect(position.x + indentOffset, position.y, labelWidth, position.height),
label
);
targetProperty0.objectReferenceValue = EditorGUI.ObjectField(
fieldRect0, GUIContent.none, targetProperty0.objectReferenceValue, property0Type, true
);
targetProperty1.objectReferenceValue = EditorGUI.ObjectField(
fieldRect1, GUIContent.none, targetProperty1.objectReferenceValue, property1Type, true
);
targetProperty2.objectReferenceValue = EditorGUI.ObjectField(
fieldRect2, GUIContent.none, targetProperty2.objectReferenceValue, property2Type, true
);
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ad305cdce04a4b80ba0a061a630911da
timeCreated: 1753263774
@@ -0,0 +1,59 @@
using System;
using UnityEditor;
using UnityEngine;
using XericUI.Core.Vessel;
using Object = UnityEngine.Object;
namespace XericUIEditor.Core.Vessel
{
[CustomPropertyDrawer(typeof(ObjectVessel<>))]
public class ObjectVesselProperty : ObjectVesselPropertyBase
{
private Type property0Type = typeof(Object);
private string originTooltip = null;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
var targetProperty0 = property.FindPropertyRelative("target");
if (targetProperty0 == null)
{
// 如果找不到字段,显示错误信息
EditorGUI.HelpBox(position, "[PROPERTY ERROR]", MessageType.Error);
EditorGUI.EndProperty();
return;
}
Type genericType = GetActualGenericType(fieldInfo.FieldType, typeof(ObjectVessel<>));
if (genericType != null && genericType.IsGenericType)
{
Type[] typeArgs = genericType.GetGenericArguments();
if (typeArgs.Length >= 1) property0Type = typeArgs[0];
// 更新Tooltip
if (string.IsNullOrEmpty(originTooltip))
{
originTooltip = $"<{property0Type?.Name}>\n{label.tooltip}";
label.tooltip = originTooltip;
}
}
targetProperty0.objectReferenceValue = EditorGUI.ObjectField(
position,
label,
targetProperty0.objectReferenceValue,
property0Type,
true
);
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2e26331650e84011aab1e2ebc4a39821
timeCreated: 1753253349
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using XericUI.Core.Vessel;
namespace XericUIEditor.Core.Vessel
{
public class ObjectVesselPropertyBase : PropertyDrawer
{
/// <summary>
/// 递归获取实际的泛型类型(处理嵌套情况)
/// </summary>
/// <param name="type"></param>
/// <param name="currentGenericDefinition"></param>
/// <returns></returns>
protected Type GetActualGenericType(Type type, Type currentGenericDefinition)
{
// 如果是泛型类型,检查是否为ObjectVessel<,>或继续递归
if (type.IsGenericType)
{
// 检查是否为ObjectVessel<,>的实例
Type genericDefinition = type.GetGenericTypeDefinition();
if (genericDefinition == currentGenericDefinition)
{
return type; // 找到目标类型
}
// 处理嵌套泛型(如List<ObjectVessel<,>>)
foreach (Type argType in type.GetGenericArguments())
{
Type nestedType = GetActualGenericType(argType, currentGenericDefinition);
if (nestedType != null)
{
return nestedType;
}
}
}
// 处理数组或其他可能的容器类型
if (type.IsArray)
{
return GetActualGenericType(type.GetElementType(), currentGenericDefinition);
}
// 检查基类
if (type.BaseType != null && type.BaseType != typeof(object))
{
return GetActualGenericType(type.BaseType, currentGenericDefinition);
}
return null; // 未找到
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 89ddf50a12de4506b000fee0b00edd4a
timeCreated: 1753261075
@@ -1,9 +1,13 @@
{
"name": "Lrss3.Xericuiactionvessel",
"name": "Lrss3.Xericuiactionvessel.Editor",
"rootNamespace": "XericUIEditor",
"references": [
"Lrss3.Xericuiactionvessel",
"Lrss3.SesothoLine.Editor"
"Lrss3.SesothoLine.Editor",
"Lrss3.Deconstruction",
"UnityEngine.UI",
"Unity.TextMeshPro",
"Unity.TextMeshPro.Editor"
],
"includePlatforms": [
"Editor"