OnBehaviourPlay not firing if clip is too small and time scale is high

I just noticed this behavior and it led me to specifically write about my problem.

I’ve implemented a re-parenting track that allows me to change the parent of a transform in Timeline. Currently, I’m using it to move transforms that I have as children to a rig out of it. The reason I’m doing this is that I need a transform to follow i.e the hand and stop at a certain point in time.

This is working pretty well in most cases, but I’ve come to notice that it is not deterministic. OnBehaviourPlay or a notification from a signal might occur later than the desired time (they don’t fire at their exact time), so the result is that the transform ends up in a different position than the one I indented. This is especially noticeable if I increase Time Scale to 5, where OnBehaviourPlay may not fire at all if the clip is too small.

To my understanding, a solution to this is not trivial, if it exists at all. For this to work, I need to calculate the rigs transform’s position, rotation and scale at my desired time and apply the result to the child transform before unparenting it. This is a completely different workflow, one that I don’t know if is feasible in terms of existing API or performance. Does anyone have an idea on how I can perhaps work with what I already have without having to remake the whole thing? Can OnBehaviourPlay happen deterministically?

Same problem here. I think it cannot.
But one solution to make it ‘deterministic’ is to make the timeline depend on the framerate.

  • [SerializeField] private float targetFrameRate = 1 / 60f;
  • [SerializeField] private PlayableDirector director;
    • private void Update()
  • {
  • if (Time.deltaTime > 0f) {
  • SetTimeScale(targetFrameRate / Time.deltaTime);
  • }
  • }
    • public void SetTimeScale(float timeScale)
  • {
  • var graph = director.playableGraph;
  • if (!graph.IsValid()) return;
  • var timelinePlayable = graph.GetRootPlayable(0);
  • if (!timelinePlayable.IsValid()) return;
    • timelinePlayable.SetSpeed(timeScale);
  • }

Source: Is there a way to guarantee the timeline will pause without crossing a certain threshold?