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