Skip to content

Instantly share code, notes, and snippets.

@Dreezn
Last active January 26, 2024 04:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dreezn/2a06f2de4a36666ef49d8c5726a6df16 to your computer and use it in GitHub Desktop.
Save Dreezn/2a06f2de4a36666ef49d8c5726a6df16 to your computer and use it in GitHub Desktop.
Getting the Clip Start End Times through to the mixer
/* 1 - Overriding CreateTrackMixer in the CustomTransformationTrack class,
getting the start & end times for each clip, and passing them to the custom clip class. */
//[Omitted...]
public class CustomTransformationTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
foreach (var clip in GetClips())
{
var customClip = clip.asset as CustomTransformationClip;
if (customClip != null)
{
customClip.CustomClipStart = clip.start;
customClip.CustomClipEnd = clip.end;
}
}
return ScriptPlayable<CustomTransformationMixerBehaviour>.Create (graph, inputCount);
}
//[Omitted...]
}
/* 2 - Overriding CreatePlayable in the CustomTransformationClip class,
passing those same start & end times of that specific clip on to the custom behaviour class. */
//[Omitted...]
public class CustomTransformationClip : PlayableAsset, ITimelineClipAsset
{
//[Omitted...]
public double CustomClipStart { get; set; }
public double CustomClipEnd { get; set; }
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<CustomTransformationBehaviour>.Create (graph, template);
playable.GetBehaviour().CustomClipStart = CustomClipStart;
playable.GetBehaviour().CustomClipEnd = CustomClipEnd;
return playable;
}
}
/* 3 - Accessing these values in the mixer, when applying the transformations.
Got the timeline 'playhead time' from https://forum.unity.com/threads/how-to-get-playable-gettime-when-not-in-play-mode.496047/ */
//[Omitted...]
public class CustomTransformationMixerBehaviour : PlayableBehaviour
{
private bool _firstFrameHappened;
private Quaternion _defaultRotation;
private Transform _trackBinding;
//[Omitted...]
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; }
//Picked up this trick from the LightControlMixerBehaviour in the DefaultPlayables examples.
if (!_firstFrameHappened)
{
_defaultRotation = _trackBinding.rotation;
_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();
double customDuration = input.CustomClipEnd - input.CustomClipStart;
float normalizedClipPosition = Mathf.Clamp01((float)((playTime - input.CustomClipStart) / customDuration));
float rotationToAdd = input.GetAngle(normalizedClipPosition);
rotation *= Quaternion.Euler(Vector3.right * rotationToAdd);
}
_trackBinding.rotation = _defaultRotation * rotation;
}
public override void OnGraphStop(Playable playable)
{
if (_trackBinding != null)
{ _trackBinding.rotation = _defaultRotation; }
base.OnGraphStop(playable);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment