Rhythm Based Action/Shooting

Hi! I’m working on a rhythm shooter. I’m trying to create a system where actions can only be performed on the beat.

I have a small, teeny idea of the work behind it, for example the beat time would be 60 / the bpm of the song, and there should be beat markers in fmod. However from there I get quite a bit lost. I don’t know how to develop a decent error margin, how to attach scripts/actions to the beat, etc.

I have already looked online and found a bit of help in terms of code, but I don’t really understand it.

Any help would be appreciated. Thanks.

Hi,

The process of tracking beats in FMOD is handled by timeline callbacks. The Timeline Callbacks scripting example provides a script that outputs the current bar and the last timeline marker encountered, but you can grab any data listed in the FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES, FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES and FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES callback documentation, such as individual beats, the current tempo or time signature, etc.

To elaborate on the general process of using a timeline callback, you’ll need an event with a tempo marker(s) and/or other marker(s). Then, in your Unity script you’ll need to:

  1. Create a callback function, and register it with the event instance with EventInstance.setCallback() - in the scripting example, by setting the function BeatEventCallback() as a TIMELINE_BEAT and TIMELINE_MARKER callback, it will be called by FMOD whenever the event reaches a new beat or marker on the timeline

  2. Create some kind of data structure to pass to the callback - in the example, that class is TimelineInfo, and it will hold the current bar and last marker encountered so that you can act on it outside of the callback

  3. Pass your data structure to the event as user data using EventInstance.setUserData()

  4. Retrieve the user data from within the callback using EventInstance.getUserData(), and act on it

The most flexible part of this process is the user data. You can basically pass whatever you want to the event, and act on it in the callback. Like in the example, you can pass variables which you set in the callback, and then act on outside of the callback e.g. set a bool in the callback and then check in Update() to call a specific method. Alternatively, you can pass a method delegate as user data and call it from within the callback itself. If you really wanted to, you could even pass a whole class instance as user data, and call methods directly from it.

As for developing an error margin, that’s something you’ll have to handle in code yourself, but it should be a fairly simple matter of tracking the time since the last beat/until the next beat, and comparing that to when the player does their input as well as an arbitrary error margin.

Hope this helps!

1 Like