Skip to content

Instantly share code, notes, and snippets.

@Dreezn
Last active February 15, 2024 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Dreezn/4dd99129ce3f77769f01dd93d3fc1932 to your computer and use it in GitHub Desktop.
Save Dreezn/4dd99129ce3f77769f01dd93d3fc1932 to your computer and use it in GitHub Desktop.
A less dirty workaround to get accurate clip start and end times
//[Omitted...]
public class CustomTransformationTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
var mixer = ScriptPlayable<CustomTransformationMixerBehaviour>.Create (graph, inputCount);
foreach (TimelineClip clip in GetClips())
{
var customClip = clip.asset as CustomTransformationClip;
if (customClip != null)
{ customClip.CustomClipReference = clip; }
}
return mixer;
}
}
//[Omitted...]
public class CustomTransformationClip : PlayableAsset, ITimelineClipAsset
{
public CustomTransformationBehaviour template = new CustomTransformationBehaviour ();
public TimelineClip CustomClipReference { get; set; }
//[Omitted...]
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<CustomTransformationBehaviour>.Create (graph, template);
playable.GetBehaviour().CustomClipReference = CustomClipReference;
return playable;
}
}
//[Omitted...]
public class CustomTransformationBehaviour : PlayableBehaviour
{
public CustomTransformation transformation;
public float angle = 90f;
public Vector3 axis = Vector3.right;
public bool reverse;
public TimelineClip CustomClipReference { get; set; }
public double CustomClipStart { get { return CustomClipReference.start; } }
public double CustomClipEnd { get { return CustomClipReference.end; } }
}
//[Omitted...]
public class CustomTransformationMixerBehaviour : PlayableBehaviour
{
private bool _firstFrameHappened;
private Quaternion _defaultRotation;
private Transform trackBinding;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
trackBinding = playerData as Transform;
if (!trackBinding)
{ return; }
int inputCount = playable.GetInputCount();
if (inputCount == 0)
{ return; }
if (!_firstFrameHappened)
{
_defaultRotation = trackBinding.localRotation;
_firstFrameHappened = true;
}
double playTime = playable.GetGraph().GetRootPlayable(0).GetTime();
Quaternion rotation = Quaternion.identity;
for (int i = 0; i < inputCount; i++)
{
var inputPlayable = (ScriptPlayable<CustomTransformationBehaviour>)playable.GetInput(i);
CustomTransformationBehaviour input = inputPlayable.GetBehaviour();
if (input.transformation == null)
{ continue; }
double customDuration = input.CustomClipEnd - input.CustomClipStart;
float normalizedClipPosition = Mathf.Clamp01((float)((playTime - input.CustomClipStart) / customDuration));
float eval = input.transformation.Evaluate(input.reverse ? 1 - normalizedClipPosition : normalizedClipPosition);
Vector3 rotationToAdd = input.axis * (input.angle * eval);
rotation *= Quaternion.Euler(rotationToAdd);
}
trackBinding.localRotation = _defaultRotation * rotation;
}
public override void OnGraphStop(Playable playable)
{
if (trackBinding != null)
{ trackBinding.localRotation = _defaultRotation; }
base.OnGraphStop(playable);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment