Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TweenMixerBehaviour.cs 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using UnityEngine;
  2. using UnityEngine.Playables;
  3. namespace Timeline.Samples
  4. {
  5. // The runtime instance of a Tween track. It is responsible for blending and setting
  6. // the final data on the transform binding.
  7. public class TweenMixerBehaviour : PlayableBehaviour
  8. {
  9. static AnimationCurve s_DefaultCurve = AnimationCurve.Linear(0.0f, 0.0f, 1.0f, 1.0f);
  10. bool m_ShouldInitializeTransform = true;
  11. Vector3 m_InitialPosition;
  12. Quaternion m_InitialRotation;
  13. // Performs blend of position and rotation of all clips connected to a track mixer
  14. // The result is applied to the track binding's (playerData) transform.
  15. public override void ProcessFrame(Playable playable, FrameData info, object playerData)
  16. {
  17. Transform trackBinding = playerData as Transform;
  18. if (trackBinding == null)
  19. return;
  20. // Get the initial position and rotation of the track binding, only when ProcessFrame is first called
  21. InitializeIfNecessary(trackBinding);
  22. Vector3 accumPosition = Vector3.zero;
  23. Quaternion accumRotation = QuaternionUtils.zero;
  24. float totalPositionWeight = 0.0f;
  25. float totalRotationWeight = 0.0f;
  26. // Iterate on all mixer's inputs (ie each clip on the track)
  27. int inputCount = playable.GetInputCount();
  28. for (int i = 0; i < inputCount; i++)
  29. {
  30. float inputWeight = playable.GetInputWeight(i);
  31. if (inputWeight <= 0)
  32. continue;
  33. Playable input = playable.GetInput(i);
  34. float normalizedInputTime = (float)(input.GetTime() / input.GetDuration());
  35. // get the clip's behaviour and evaluate the progression along the curve
  36. TweenBehaviour tweenInput = GetTweenBehaviour(input);
  37. float tweenProgress = GetCurve(tweenInput).Evaluate(normalizedInputTime);
  38. // calculate the position's progression along the curve according to the input's (clip) weight
  39. if (tweenInput.shouldTweenPosition)
  40. {
  41. totalPositionWeight += inputWeight;
  42. accumPosition += TweenPosition(tweenInput, tweenProgress, inputWeight);
  43. }
  44. // calculate the rotation's progression along the curve according to the input's (clip) weight
  45. if (tweenInput.shouldTweenRotation)
  46. {
  47. totalRotationWeight += inputWeight;
  48. accumRotation = TweenRotation(tweenInput, accumRotation, tweenProgress, inputWeight);
  49. }
  50. }
  51. // Apply the final position and rotation values in the track binding
  52. trackBinding.position = accumPosition + m_InitialPosition * (1.0f - totalPositionWeight);
  53. trackBinding.rotation = accumRotation.Blend(m_InitialRotation, 1.0f - totalRotationWeight);
  54. trackBinding.rotation.Normalize();
  55. }
  56. void InitializeIfNecessary(Transform transform)
  57. {
  58. if (m_ShouldInitializeTransform)
  59. {
  60. m_InitialPosition = transform.position;
  61. m_InitialRotation = transform.rotation;
  62. m_ShouldInitializeTransform = false;
  63. }
  64. }
  65. Vector3 TweenPosition(TweenBehaviour tweenInput, float progress, float weight)
  66. {
  67. Vector3 startPosition = m_InitialPosition;
  68. if (tweenInput.startLocation != null)
  69. {
  70. startPosition = tweenInput.startLocation.position;
  71. }
  72. Vector3 endPosition = m_InitialPosition;
  73. if (tweenInput.endLocation != null)
  74. {
  75. endPosition = tweenInput.endLocation.position;
  76. }
  77. return Vector3.Lerp(startPosition, endPosition, progress) * weight;
  78. }
  79. Quaternion TweenRotation(TweenBehaviour tweenInput, Quaternion accumRotation, float progress, float weight)
  80. {
  81. Quaternion startRotation = m_InitialRotation;
  82. if (tweenInput.startLocation != null)
  83. {
  84. startRotation = tweenInput.startLocation.rotation;
  85. }
  86. Quaternion endRotation = m_InitialRotation;
  87. if (tweenInput.endLocation != null)
  88. {
  89. endRotation = tweenInput.endLocation.rotation;
  90. }
  91. Quaternion desiredRotation = Quaternion.Lerp(startRotation, endRotation, progress);
  92. return accumRotation.Blend(desiredRotation.NormalizeSafe(), weight);
  93. }
  94. static TweenBehaviour GetTweenBehaviour(Playable playable)
  95. {
  96. ScriptPlayable<TweenBehaviour> tweenInput = (ScriptPlayable<TweenBehaviour>)playable;
  97. return tweenInput.GetBehaviour();
  98. }
  99. static AnimationCurve GetCurve(TweenBehaviour tween)
  100. {
  101. if (tween == null || tween.curve == null)
  102. return s_DefaultCurve;
  103. return tween.curve;
  104. }
  105. }
  106. }