C# OnValueChanged在可脚本对象统一中
我是否可以在C#Unity中的类扩展ScriptableObject中的变量/属性上使用某些类型的OnValueChanged()或OnValueChanged属性,以便在inspector中更改其资产文件中该变量/属性的值时调用另一个方法?还是有其他方法可以达到这个目的?您可以用它来存档。下面是一个可以监视字段和属性更改的最小示例 公共类CustomType:ScriptableObject{ 公共领域; 私有财产; 公共财产{ 获取{return myProperty;} 设置{ 如果(值!=myProperty){ //在这里做事 myProperty=值; } } } OnMyFieldChanged上的公共无效(int-from,int-to){ //在这里做事 } } #如果统一编辑器 [CustomEditor(typeof(CustomType))] 类CustomTypeEditor:Editor{ 公共覆盖无效OnInspectorGUI(){ CustomType CustomType=(CustomType)目标; int field=EditorGUILayout.IntField(“field”,customType.myField); 如果(字段!=customType.myField){ customType.OnMyFieldChanged(customType.myField,字段); customType.myField=字段; } customType.MyProperty=EditorGUILayout.IntField(“属性”,customType.MyProperty); } } #恩迪夫 只有在inspector中打开此对象时,此操作才有效。如果要将此对象作为另一个对象的一部分,则必须改用。这些编辑器与自定义编辑器非常相似。C# OnValueChanged在可脚本对象统一中,c#,unity3d,C#,Unity3d,我是否可以在C#Unity中的类扩展ScriptableObject中的变量/属性上使用某些类型的OnValueChanged()或OnValueChanged属性,以便在inspector中更改其资产文件中该变量/属性的值时调用另一个方法?还是有其他方法可以达到这个目的?您可以用它来存档。下面是一个可以监视字段和属性更改的最小示例 公共类CustomType:ScriptableObject{ 公共领域; 私有财产; 公共财产{ 获取{return myProperty;} 设置{ 如果(值!
这是一个非常基本的示例,可以说明使用自定义编辑器可以解决问题,但如果打算使用它们,您可能希望进一步了解该主题。如果您的类不是从monobehavior for OnValidate()继承的,则可以在中找到一个简单的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++;
}
}
自由资产具有一个属性,您可以使用该属性在值通过检查器更改时触发该属性。下面是一个在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);
}
[下拉列表(“LevelNames”)]
[OnValueChanged(“OnLevel更改”)]
公共字符串currentLevelName;
私有列表级别名称{
得到{
返回新列表(){“级别1”、“级别2”、“级别3”};
}
}
私有void OnLevelChanged(){
LogFormat(“OnLevelChanged:{0}”,currentLevelName);
}
您可以执行OnValidate
功能来检测inspector中的值何时更改。但是,现在更改值的唯一方法是使用私有“备份字段”并将该值与序列化字段进行比较。您要监视的值是否为自定义类型?如果是,您可以向其添加事件处理程序。是的,它是自定义类型,并且是类扩展ScriptableObject中的变量。我创建了该类的一个资产文件,我希望在通过inspector更改该变量(在资产文件中)的值时调用一个方法。这个方法应该是在那个类中的好主意-谢谢-但是这段代码在编写时似乎不适用于复合检查器字段,比如System.Serializable structs。此时会出现小的“展开”箭头,每次单击回调时都会调用它(并按预期进行切换),但较低级别结构的字段不再显示在检查器中。关于如何扩展它以使其在这种情况下工作,您有什么想法吗?