Search Unity

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

Discussion in 'Timeline' started by TheHeftyCoder, Apr 9, 2023.

  1. TheHeftyCoder

    TheHeftyCoder

    Joined:
    Oct 29, 2016
    Posts:
    91
    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?
     
  2. Sarai

    Sarai

    Joined:
    Jul 20, 2014
    Posts:
    30
    Same problem here. I think it cannot.
    But one solution to make it 'deterministic' is to make the timeline depend on the framerate.

    1. [SerializeField] private float targetFrameRate = 1 / 60f;
    2. [SerializeField] private PlayableDirector director;

    3. private void Update()
    4. {
    5. if (Time.deltaTime > 0f) {
    6. SetTimeScale(targetFrameRate / Time.deltaTime);
    7. }
    8. }

    9. public void SetTimeScale(float timeScale)
    10. {
    11. var graph = director.playableGraph;
    12. if (!graph.IsValid()) return;
    13. var timelinePlayable = graph.GetRootPlayable(0);
    14. if (!timelinePlayable.IsValid()) return;

    15. timelinePlayable.SetSpeed(timeScale);
    16. }
    Source: https://forum.unity.com/threads/is-...sing-a-certain-threshold.744596/#post-9605534