unity3d 泛型类的自定义属性绘制器C# Unity

yrdbyhpb  于 2023-01-26  发布在  C#
关注(0)|答案(4)|浏览(252)

在检查器中显示Serializable泛型类时遇到问题。
Serializable泛型类如下所示:

using UnityEngine;
using System;
using System.Collections;

[Serializable]
public class GenericClass<T> where T : struct
{
    [SerializeField]
    string _serializedString;

    public string SerializedString
    {
        get { return _serializedString; }
        set { _serializedString = value; }
    }

    ... // Functions using the generic type
}

自定义属性抽屉如下所示:

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(GenericClass<>))]
public class GenericClassDrawer: PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        SerializedProperty stringProperty = property.FindPropertyRelative("SerializedString");

        stringProperty.stringValue = EditorGUI.TextField(position, stringProperty.stringValue);
    }
}

我使用的测试泛型类的MonoBehaviour如下所示:

using UnityEngine;
using System.Collections;

public class TestClass : MonoBehaviour 
{
    enum BasicEnum
    {
        First,
        Second,
        Third,
        Fourth
    }

    [SerializeField]
    GenericClass<BasicEnum> _editorEnum;
}

使用当前代码,MonoBehaviour TestClass不会在检查器中显示任何内容。它应该显示一个文本字段。
我相信这是由于类的泛型性质,但我一直无法找到任何人使用自定义属性抽屉与泛型类的例子。
我的问题是--这可能吗?我在代码中遗漏了什么,让文本字段按预期显示?如果当前的代码不可能,那么对于泛型类的属性抽屉有什么解决方法吗?
感谢您抽出宝贵时间!

k4emjkb1

k4emjkb11#

这是行不通的,因为Unity目前(4.x/5.0)没有序列化泛型类。序列化泛型的一个技巧是从它们继承。例如,在这种情况下,你可以:

[Serializable]
class GenericClassInt: GenericClass<int> { ... }

[Serializable]
class GenericClassFloat: GenericClass<float> { ... }

然后您可以使用字段编辑器:

[CustomPropertyDrawer(typeof(GenericClassInt))]
[CustomPropertyDrawer(typeof(GenericClassFloat))]
public class GenericClassDrawer: PropertyDrawer { ... }

这并不像它所能做到的那样优雅,但却解决了问题。

wmvff8tz

wmvff8tz2#

一种解决方法是从非泛型抽象基类继承。这是因为property.FindPropertyRelative(...)在运行时而不是编译时查找值,所以它在具体的运行时示例中查找值。

[Serializable]
public abstract class Generic { }

[Serializable]
public abstract class Generic<T> : Generic {
    public T value;
}
[Serializable]
public class GenericInt : Generic<int> { }
[Serializable]
public class GenericFloat : Generic<float> { }

[CustomPropertyDrawer (typeof (Generic), true)]
public class IngredientDrawer : PropertyDrawer {
    public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        EditorGUI.BeginProperty (position, label, property);
        position = EditorGUI.PrefixLabel (position, GUIUtility.GetControlID (FocusType.Passive), label);
        EditorGUI.PropertyField (position, property.FindPropertyRelative ("value"), GUIContent.none);
        EditorGUI.EndProperty ();
    }
}
cwtwac6a

cwtwac6a3#

基于您的代码:您正在通过名称SerializedString(对应于属性)和非序列化字段进行请求。请输入以下代码以接收SerializedProperty:
序列化属性字符串属性=属性.查找属性相对(“_序列化字符串”);
您应该请求FIELD,而不是属性

disbfnqx

disbfnqx4#

我不是绝对肯定,但在我过去的经验中,Unity不支持泛型类的CustomPropertyDrawers。

相关问题