13
\$\begingroup\$

I am planning the development of a game in Unity3D, and trying to come to terms with what the engine has already provided, and what I must code myself.

The game itself is going to be a rhythm game, which means synching audio and graphical events so that they always play when they're supposed to. What I'm looking to avoid is a potential scenario of lag where either the audio or the graphics starts to progress faster than the other.

When we discussed this type of coordinating system in my game design class back at university, my professor called this type of design a "Timeline" class. The idea being that you can instantiate one or more of these to progress at different rates, schedule things to happen in the future, and synch up periodic events. However, calling this a "Timeline" class seems to have been limited to my professor himself, as googling for whether a certain API features "Timeline" functionality has been a fruitless endeavor.

Is there some more common name for this kind of functionality? Does Unity have any pre-existing methods to coordinate the scheduling of events like this, or is this the kind of thing that needs to be built onto the engine? And if it does, I'd appreciate being pointed towards some tutorials!

\$\endgroup\$
1
  • \$\begingroup\$ I have also used similar Timeline classes (they even had the same name). A more common name for the pattern is unknown to me, but it is probably often implemented via functional-reactive programming, coroutines or other asynchronous concepts. \$\endgroup\$
    – interphx
    Nov 7, 2016 at 16:43

3 Answers 3

10
\$\begingroup\$

While this functionality isn't available in Unity, a basic implementation of such a timeline shouldn't be too hard to do.

Here's how I would go about that:

  • Your Timeline class internally uses a priority-queue as data-structure to store events.
  • An event could just be a time and a callback. So adding events to the timeline would be as simple as: timeline.AddEvent(0.25f, MyCallback).
  • With every Update, the timeline class would:

    1. Increment the playhead (a simple float) by the elapsed time
    2. Check the head of the priority queue and remove and call the callback of all the events that have a priority (eg. time) smaller or equal to the current playhead.

If you need some sort of rewind or replay functionality, it would of course be foolish to remove all the events from the queue (meaning you would have to add them again when rewound). Instead you could also use an array that holds your events. An event would consist of a Time and Callback. You would have to keep your array sorted by Time.

Then instead of removing items from the array, you would keep track of the current array-index, and with every update seek ahead from that index and execute all callbacks with Playhead >= Time while also increasing the index accordingly.

Implementing a faster playback-speed works with both implementations and would be as simple as:

Playhead += Time.deltaTime * playbackSpeed
\$\endgroup\$
1
  • 2
    \$\begingroup\$ "Increment the playhead (a simple float) by the elapsed time" - If you do this you'll get aggregated floating-point errors. You should use Time.time (the time since the game started) instead. \$\endgroup\$ Jan 31, 2014 at 23:31
4
\$\begingroup\$

No, Unity3D doesn't have such an API out of the box.

It does support coroutines, though, and I suggest you look into them. Coroutines generally make scheduling and syncing events really easy.

\$\endgroup\$
1
\$\begingroup\$

I'm not sure if this is new since the answers in 2012, but Unity actually does have support for timeline control via the (Legacy) Animation Editor.

Although this feature is intended mainly for animating object parameters with curves, it includes the ability to trigger scripts on Animation Events. These scripts could drive your graphics and audio.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .