Unity中SerializeReference的Redo功能失效问题求助
Unity UI Elements PropertyDrawer 撤销(Undo)正常但重做(Redo)失效问题
我正在利用UI Elements的PropertyField类制作PropertyDrawer,设置了下拉菜单用于选择平滑算法类型。目前Undo功能正常,但Redo功能完全失效。我尝试了Undo类的多种方法(比如FlushUndoRecordObjects、IncrementCurrentGroup、RecordObject),但Redo始终无法触发。
示例截图
- 第一种平滑类型

- 第二种平滑类型

相关代码
using System; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; namespace Whatever { public class SmoothingTest : MonoBehaviour { public Smoothing Smoothing; } [Serializable] public sealed class Smoothing { [SerializeField] internal SmoothingType MethodType; [SerializeReference] internal SmoothingMethod Method = new SmoothingMethodExponentialSingle(); public float Smooth(float value) { return Method.Smooth(value); } } [CustomPropertyDrawer(typeof(Smoothing))] internal sealed class SmoothingDrawer : PropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { var pf = new PropertyField(property, preferredLabel); var sp = property.FindPropertyRelative(nameof(Smoothing.MethodType)); pf.TrackPropertyValue(sp, OnMethodTypeChanged); return pf; } private static void OnMethodTypeChanged(SerializedProperty property) { var parent = property.GetParentProperty(); var method = parent.FindPropertyRelative(nameof(Smoothing.Method)); var type = (SmoothingType)property.intValue; method.managedReferenceValue = type switch { SmoothingType.ExponentialSingle => new SmoothingMethodExponentialSingle(), SmoothingType.ExponentialDouble => new SmoothingMethodExponentialDouble(), _ => throw new NotSupportedException(type.ToString()) }; method.serializedObject.ApplyModifiedProperties(); } } public static class SerializedPropertyExtensions // TODO move { public static SerializedProperty GetParentProperty(this SerializedProperty property) { var path = property.propertyPath; var last = path.LastIndexOf('.'); path = path[..last]; var prop = property.serializedObject.FindProperty(path); return prop; } } public enum SmoothingType { ExponentialSingle, ExponentialDouble } [Serializable] public abstract class SmoothingMethod { [SerializeField] private float Last; public float Smooth(float value) { Last = SmoothCore(value, Last); return Last; } protected abstract float SmoothCore(float value, float last); } [Serializable] public sealed class SmoothingMethodExponentialSingle : SmoothingMethod { public float Alpha; protected override float SmoothCore(float value, float last) { // https://en.wikipedia.org/wiki/Exponential_smoothing#Basic_(simple)_exponential_smoothing return Alpha * value + (1 - Alpha) * last; // https://en.wikipedia.org/wiki/Exponential_smoothing#%22Exponential%22_naming return last + Alpha * (value - last); } } [Serializable] public sealed class SmoothingMethodExponentialDouble : SmoothingMethod { public float Alpha; public float Beta; public float BetaLast; // TODO private protected override float SmoothCore(float value, float last) { // https://en.wikipedia.org/wiki/Exponential_smoothing#Double_exponential_smoothing_(Holt_linear) var st = Alpha * last + (1 - Alpha) * (last + BetaLast); var bt = Beta * (st - last) + (1 - Beta) * BetaLast; BetaLast = bt; return st; } } }
内容的提问来源于stack exchange,提问作者aybe
相关产品推荐
相关产品推荐

