我創建了一個自定義的 PropertyDrawer,它針對用我的屬性裝飾的某個欄位,顯示了來自同一腳本中參考的影片物件的引數。
這樣,我就可以確保該欄位的值是參考影片器中的有效引數。
這是我的代碼:
public class AnimationParamAttribute : PropertyAttribute
{
public string AnimatorName { get; }
public AnimatorControllerParameterType[] AllowedParameters { get; }
public AnimationParamAttribute(string animatorName, params AnimatorControllerParameterType[] allowedParameters)
{
AnimatorName = animatorName;
this.AllowedParameters = allowedParameters;
}
}
public class AnimationController : MonoBehaviour
{
[SerializeField] private Animator animator;
[SerializeField, AnimationParam(nameof(animator), AnimatorControllerParameterType.Trigger)]
private string trigger;
[ContextMenu("Print value")]
private void PrintValue()
{
Debug.Log(trigger);
}
public void StartAnimation()
{
animator.SetTrigger(trigger);
}
}
我的PropertyDrawer樣子是這樣的:
[CustomPropertyDrawer(typeof(AnimationParamAttribute))]
public class AnimationParamDrawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
AnimationParamAttribute a = (AnimationParamAttribute)attribute;
if (property.propertyType == SerializedPropertyType.String)
{
var targetObject = property.serializedObject.targetObject;
var field = targetObject.GetType().GetField(a.AnimatorName,
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Animator animator = field?.GetValue(targetObject) as Animator;
if (animator == null)
{
EditorGUI.LabelField(position, label.text, "Select an animator.");
return;
}
var options = animator.parameters
.Where(parameter => a.AllowedParameters.Contains(parameter.type))
.Select(parameter => parameter.name)
.ToArray();
var s = string.Join(", ", options);
Debug.Log($"Options: {s}");
int selection = Array.IndexOf(options, property.stringValue);
Debug.Log($"{property.stringValue} is option {selection}");
if (selection < 0) selection = 0;
position = EditorGUI.PrefixLabel(position, label);
EditorGUI.BeginProperty(position, label, property);
EditorGUI.BeginChangeCheck();
selection = EditorGUI.Popup(position, selection, options);
if (EditorGUI.EndChangeCheck())
{
Debug.Log($"New selection: {selection}");
property.stringValue = options[selection];
}
EditorGUI.EndProperty();
}
else
EditorGUI.LabelField(position, label.text, "Use with string fields.");
}
}
代碼作業正常,但由于某種原因,當我更改影片物件中的引數時,animator.parameters回傳一個空陣列。
當我修改代碼以強制 Unity 重新編譯時,我得到了正確的值并且代碼再次運行。
這是什么原因,我該如何解決?
uj5u.com熱心網友回復:
在您的AnimationPropertyDrawer檔案中,您希望“重新系結”所有屬性以便我們查看最新值。這是一個 Editor PropertyDrawer,所以我們期待一些魔法是有代價的。幸運的是,這不會影響構建。
嘗試這個:
Animator animator = field?.GetValue(targetObject) as Animator;
if ( animator == null )
{
EditorGUI.LabelField ( position, label.text, "Select an animator." );
return;
}
animator.Rebind ( );
var options = animator.parameters
.Where(parameter => a.AllowedParameters.Contains(parameter.type))
.Select(parameter => parameter.name)
.ToArray();
注意額外的行animator.Rebind ( );。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/534925.html
標籤:C#unity3d
上一篇:按順序淡出影像
