NormalizedAnimationCurveAttribute.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using System;
  2. using UnityEngine;
  3. #if UNITY_EDITOR
  4. using UnityEditor;
  5. #endif
  6. namespace UnityUIPlayables
  7. {
  8. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
  9. internal class NormalizedAnimationCurveAttribute : MultiPropertyAttribute
  10. {
  11. private readonly bool _normalizeTime;
  12. private readonly bool _normalizeValue;
  13. public NormalizedAnimationCurveAttribute(bool normalizeValue = true, bool normalizeTime = true)
  14. {
  15. _normalizeValue = normalizeValue;
  16. _normalizeTime = normalizeTime;
  17. }
  18. #if UNITY_EDITOR
  19. public override void OnPostGUI(Rect position, SerializedProperty property, bool changed)
  20. {
  21. if (changed)
  22. {
  23. if (_normalizeValue)
  24. {
  25. property.animationCurveValue = NormalizeValue(property.animationCurveValue);
  26. }
  27. if (_normalizeTime)
  28. {
  29. property.animationCurveValue = NormalizeTime(property.animationCurveValue);
  30. }
  31. }
  32. }
  33. private static AnimationCurve NormalizeValue(AnimationCurve curve)
  34. {
  35. var keys = curve.keys;
  36. if (keys.Length <= 0)
  37. {
  38. return curve;
  39. }
  40. var minVal = keys[0].value;
  41. var maxVal = minVal;
  42. foreach (var t in keys)
  43. {
  44. minVal = Mathf.Min(minVal, t.value);
  45. maxVal = Mathf.Max(maxVal, t.value);
  46. }
  47. var range = maxVal - minVal;
  48. var valScale = range < 1 ? 1 : 1 / range;
  49. var valOffset = 0f;
  50. if (range < 1)
  51. {
  52. if (minVal > 0 && minVal + range <= 1)
  53. {
  54. valOffset = minVal;
  55. }
  56. else
  57. {
  58. valOffset = 1 - range;
  59. }
  60. }
  61. for (var i = 0; i < keys.Length; ++i)
  62. {
  63. keys[i].value = (keys[i].value - minVal) * valScale + valOffset;
  64. }
  65. curve.keys = keys;
  66. return curve;
  67. }
  68. private static AnimationCurve NormalizeTime(AnimationCurve curve)
  69. {
  70. var keys = curve.keys;
  71. if (keys.Length <= 0)
  72. {
  73. return curve;
  74. }
  75. var minTime = keys[0].time;
  76. var maxTime = minTime;
  77. foreach (var t in keys)
  78. {
  79. minTime = Mathf.Min(minTime, t.time);
  80. maxTime = Mathf.Max(maxTime, t.time);
  81. }
  82. var range = maxTime - minTime;
  83. var timeScale = range < 0.0001f ? 1 : 1 / range;
  84. for (var i = 0; i < keys.Length; ++i)
  85. {
  86. keys[i].time = (keys[i].time - minTime) * timeScale;
  87. }
  88. curve.keys = keys;
  89. return curve;
  90. }
  91. #endif
  92. }
  93. }