例如UnityEngine.UI.Text
它包含text
变量,用于将文本值设置为字符串。
现在,在我自己的类中,我使用property(get; set)而不是直接访问变量,这使我能够在设置新值时更新视图或触发某些事件。问题是当使用属性(get set)时,它不会在检查器中甚至在集成测试工具中显示此字段。
但是Unity的文本组件决定不使用get set。在我看来,我认为处理价值变得不舒服。
问题是UnityEngine.UI.Text
变量中的原始text
如何处理此问题?
我认为这不只是OnValidate()
,因为它只能在编辑器上运行。但text
变量也适用于运行时脚本。
加载脚本或值时调用此函数 在检查器中更改(仅在编辑器中调用)。 https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnValidate.html
答案 0 :(得分:1)
我使用的另一种解决方案。
public T car;
private T _car;
public Car {
get {
return this._car;
}
set {
this._car = value;
}
}
public void OnValidate() {
this.Car = car;
}
答案 1 :(得分:0)
除了检查文本是否相对于缓存的“之前”值更改之外,没有其他方法。如果没有扩展属性,您只需手动执行此操作即可。
答案 2 :(得分:0)
你不能。这就是为什么Unity中的大多数组件都会轮询它们依赖于每一帧的价值。
如果您确实想要检测更改,可以执行以下操作:
public sometype Field;
private sometype _previousValueOfField;
public void Awake()
{
_previousValueOfField = Field;
}
public void Update()
{
if(Field != _previousValueOfField)
{
_previousValueOfField = Field;
// Execute some logic regarding the change of the field there
}
}
(顺便说一下,公共领域是邪恶的另一个原因,我讨厌Unity依赖它们。)
答案 3 :(得分:0)
如果您不使用单行为(因此可以执行OnValidate())或要进行轮询,则可以选择沿着this gist的行将属性归因字符串分配给方法反射解决方案。同样在下面的简单实现和示例中:
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++;
}
}