123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- using System;
- using UnityEngine;
- using UnityEngine.Playables;
- public class TransformTweenMixerBehaviour : PlayableBehaviour
- {
- bool m_FirstFrameHappened;
- public override void ProcessFrame(Playable playable, FrameData info, object playerData)
- {
- Transform trackBinding = playerData as Transform;
- if(trackBinding == null)
- return;
- Vector3 defaultPosition = trackBinding.position;
- Quaternion defaultRotation = trackBinding.rotation;
- int inputCount = playable.GetInputCount ();
- float positionTotalWeight = 0f;
- float rotationTotalWeight = 0f;
- Vector3 blendedPosition = Vector3.zero;
- Quaternion blendedRotation = new Quaternion(0f, 0f, 0f, 0f);
- for (int i = 0; i < inputCount; i++)
- {
- ScriptPlayable<TransformTweenBehaviour> playableInput = (ScriptPlayable<TransformTweenBehaviour>)playable.GetInput (i);
- TransformTweenBehaviour input = playableInput.GetBehaviour ();
- if(input.endLocation == null)
- continue;
- float inputWeight = playable.GetInputWeight(i);
- if (!m_FirstFrameHappened && !input.startLocation)
- {
- input.startingPosition = defaultPosition;
- input.startingRotation = defaultRotation;
- }
- float normalisedTime = (float)(playableInput.GetTime() / playableInput.GetDuration ());
- float tweenProgress = input.EvaluateCurrentCurve(normalisedTime);
- if (input.tweenPosition)
- {
- positionTotalWeight += inputWeight;
- blendedPosition += Vector3.Lerp(input.startingPosition, input.endLocation.position, tweenProgress) * inputWeight;
- }
- if (input.tweenRotation)
- {
- rotationTotalWeight += inputWeight;
- Quaternion desiredRotation = Quaternion.Lerp(input.startingRotation, input.endLocation.rotation, tweenProgress);
- desiredRotation = NormalizeQuaternion(desiredRotation);
- if (Quaternion.Dot (blendedRotation, desiredRotation) < 0f)
- {
- desiredRotation = ScaleQuaternion (desiredRotation, -1f);
- }
- desiredRotation = ScaleQuaternion(desiredRotation, inputWeight);
- blendedRotation = AddQuaternions (blendedRotation, desiredRotation);
- }
- }
- blendedPosition += defaultPosition * (1f - positionTotalWeight);
- Quaternion weightedDefaultRotation = ScaleQuaternion (defaultRotation, 1f - rotationTotalWeight);
- blendedRotation = AddQuaternions (blendedRotation, weightedDefaultRotation);
- trackBinding.position = blendedPosition;
- trackBinding.rotation = blendedRotation;
-
- m_FirstFrameHappened = true;
- }
- public override void OnPlayableDestroy (Playable playable)
- {
- m_FirstFrameHappened = false;
- }
- static Quaternion AddQuaternions (Quaternion first, Quaternion second)
- {
- first.w += second.w;
- first.x += second.x;
- first.y += second.y;
- first.z += second.z;
- return first;
- }
- static Quaternion ScaleQuaternion (Quaternion rotation, float multiplier)
- {
- rotation.w *= multiplier;
- rotation.x *= multiplier;
- rotation.y *= multiplier;
- rotation.z *= multiplier;
- return rotation;
- }
- static float QuaternionMagnitude (Quaternion rotation)
- {
- return Mathf.Sqrt ((Quaternion.Dot (rotation, rotation)));
- }
- static Quaternion NormalizeQuaternion (Quaternion rotation)
- {
- float magnitude = QuaternionMagnitude (rotation);
- if (magnitude > 0f)
- return ScaleQuaternion (rotation, 1f / magnitude);
- Debug.LogWarning ("Cannot normalize a quaternion with zero magnitude.");
- return Quaternion.identity;
- }
- }
|