123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- using UnityEngine;
- using UnityEngine.Playables;
-
- namespace Timeline.Samples
- {
- // The runtime instance of a Tween track. It is responsible for blending and setting
- // the final data on the transform binding.
- public class TweenMixerBehaviour : PlayableBehaviour
- {
- static AnimationCurve s_DefaultCurve = AnimationCurve.Linear(0.0f, 0.0f, 1.0f, 1.0f);
-
- bool m_ShouldInitializeTransform = true;
- Vector3 m_InitialPosition;
- Quaternion m_InitialRotation;
-
- // Performs blend of position and rotation of all clips connected to a track mixer
- // The result is applied to the track binding's (playerData) transform.
- public override void ProcessFrame(Playable playable, FrameData info, object playerData)
- {
- Transform trackBinding = playerData as Transform;
-
- if (trackBinding == null)
- return;
-
- // Get the initial position and rotation of the track binding, only when ProcessFrame is first called
- InitializeIfNecessary(trackBinding);
-
- Vector3 accumPosition = Vector3.zero;
- Quaternion accumRotation = QuaternionUtils.zero;
-
- float totalPositionWeight = 0.0f;
- float totalRotationWeight = 0.0f;
-
- // Iterate on all mixer's inputs (ie each clip on the track)
- int inputCount = playable.GetInputCount();
- for (int i = 0; i < inputCount; i++)
- {
- float inputWeight = playable.GetInputWeight(i);
- if (inputWeight <= 0)
- continue;
-
- Playable input = playable.GetInput(i);
- float normalizedInputTime = (float)(input.GetTime() / input.GetDuration());
-
- // get the clip's behaviour and evaluate the progression along the curve
- TweenBehaviour tweenInput = GetTweenBehaviour(input);
- float tweenProgress = GetCurve(tweenInput).Evaluate(normalizedInputTime);
-
- // calculate the position's progression along the curve according to the input's (clip) weight
- if (tweenInput.shouldTweenPosition)
- {
- totalPositionWeight += inputWeight;
- accumPosition += TweenPosition(tweenInput, tweenProgress, inputWeight);
- }
-
- // calculate the rotation's progression along the curve according to the input's (clip) weight
- if (tweenInput.shouldTweenRotation)
- {
- totalRotationWeight += inputWeight;
- accumRotation = TweenRotation(tweenInput, accumRotation, tweenProgress, inputWeight);
- }
- }
-
- // Apply the final position and rotation values in the track binding
- trackBinding.position = accumPosition + m_InitialPosition * (1.0f - totalPositionWeight);
- trackBinding.rotation = accumRotation.Blend(m_InitialRotation, 1.0f - totalRotationWeight);
- trackBinding.rotation.Normalize();
- }
-
- void InitializeIfNecessary(Transform transform)
- {
- if (m_ShouldInitializeTransform)
- {
- m_InitialPosition = transform.position;
- m_InitialRotation = transform.rotation;
- m_ShouldInitializeTransform = false;
- }
- }
-
- Vector3 TweenPosition(TweenBehaviour tweenInput, float progress, float weight)
- {
- Vector3 startPosition = m_InitialPosition;
- if (tweenInput.startLocation != null)
- {
- startPosition = tweenInput.startLocation.position;
- }
-
- Vector3 endPosition = m_InitialPosition;
- if (tweenInput.endLocation != null)
- {
- endPosition = tweenInput.endLocation.position;
- }
-
- return Vector3.Lerp(startPosition, endPosition, progress) * weight;
- }
-
- Quaternion TweenRotation(TweenBehaviour tweenInput, Quaternion accumRotation, float progress, float weight)
- {
- Quaternion startRotation = m_InitialRotation;
- if (tweenInput.startLocation != null)
- {
- startRotation = tweenInput.startLocation.rotation;
- }
-
- Quaternion endRotation = m_InitialRotation;
- if (tweenInput.endLocation != null)
- {
- endRotation = tweenInput.endLocation.rotation;
- }
-
- Quaternion desiredRotation = Quaternion.Lerp(startRotation, endRotation, progress);
- return accumRotation.Blend(desiredRotation.NormalizeSafe(), weight);
- }
-
- static TweenBehaviour GetTweenBehaviour(Playable playable)
- {
- ScriptPlayable<TweenBehaviour> tweenInput = (ScriptPlayable<TweenBehaviour>)playable;
- return tweenInput.GetBehaviour();
- }
-
- static AnimationCurve GetCurve(TweenBehaviour tween)
- {
- if (tween == null || tween.curve == null)
- return s_DefaultCurve;
- return tween.curve;
- }
- }
- }
|