Scriptable Object Unity中的OnValueChanged

时间:2018-01-12 10:12:45

标签: c# unity3d unityscript

我可以在C#Unity中的类Extented ScriptableObject中的变量/属性上使用某些类型的OnValueChanged()或OnValueChanged属性,以便在检查器中更改其资产文件中的变量/属性的值时调用另一个方法吗?或者无论如何都要为此目的服务?

3 个答案:

答案 0 :(得分:1)

您可以使用Custom Editors对此进行归档。这是一个可以监视字段和属性更改的最小示例

public class SchoolModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ApiUrl { get; set; }
    public byte[] LogoBytes { get; set; }
}

只有在检查器中打开此对象时,才能执行此操作。如果您希望此对象作为另一个对象的一部分,则必须使用Property Drawers。这些与自定义编辑器非常相似。 这是一个非常基本的示例,表明可以使用自定义编辑器解决您的问题,但如果您打算使用它们,您可能希望更多地了解该主题。

答案 1 :(得分:0)

如果您的类不是继承自OnValidate()的monobehavior或不想为每个类创建自定义编辑器,则可以在this gist中找到一个简单的propertydrawer解决方案。同样在下面的简单实现和示例中:

using System.Linq;
using UnityEngine;
using UnityEditor;
using System.Reflection;

public class OnChangedCallAttribute : PropertyAttribute
{
    public string methodName;
    public OnChangedCallAttribute(string methodNameNoArguments)
    {
        methodName = methodNameNoArguments;
    }
}

#if UNITY_EDITOR

[CustomPropertyDrawer(typeof(OnChangedCallAttribute))]
public class OnChangedCallAttributePropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginChangeCheck();
        EditorGUI.PropertyField(position, property);
        if(EditorGUI.EndChangeCheck())
        {
            OnChangedCallAttribute at = attribute as OnChangedCallAttribute;
            MethodInfo method = property.serializedObject.targetObject.GetType().GetMethods().Where(m => m.Name == at.methodName).First();

            if (method != null && method.GetParameters().Count() == 0)// Only instantiate methods with 0 parameters
                method.Invoke(property.serializedObject.targetObject, null);
        }
    }
}

#endif

示例:

using UnityEngine;

public class OnChangedCallTester : MonoBehaviour
{
    public bool UpdateProp = true;

    [SerializeField]
    [OnChangedCall("ImChanged")]
    private int myPropVar;

    public int MyProperty
    {
        get { return myPropVar; }
        set { myPropVar = value; ImChanged();  }
    }


    public void ImChanged()
    {
        Debug.Log("I have changed to" + myPropVar);
    }

    private void Update()
    {
        if(UpdateProp)
            MyProperty++;
    }
}

答案 2 :(得分:0)

免费的NaughtyAttributes资产具有属性OnValueChanged,当通过Inspector更改值时,可以使用该属性来触发。这是一个在检查器中可见的下拉列表的示例:

[Dropdown("LevelNames")]
[OnValueChanged("OnLevelChanged")]
public string currentLevelName;

private List<string> LevelNames {
    get {
        return new List<string>() { "Level 1", "Level 2", "Level 3" };
    }
}

private void OnLevelChanged() {
    Debug.LogFormat("OnLevelChanged: {0}", currentLevelName);
}