# Rhythm Based Action/Shooting

**URL:** https://qa.fmod.com/t/rhythm-based-action-shooting/19644
**Category:** FMOD Studio
**Tags:** csharp, unity
**Created:** [December 14, 2022, 7:05pm UTC](https://qa.fmod.com/t/rhythm-based-action-shooting/19644 "2022-12-14T19:05:56Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![JohnGreska](https://avatars.discourse-cdn.com/v4/letter/j/f05b48/32.png) [@JohnGreska](https://qa.fmod.com/u/JohnGreska)
#### Post date: [December 14, 2022, 7:05pm UTC](https://qa.fmod.com/t/rhythm-based-action-shooting/19644/1 "2022-12-14T19:05:56Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![Leah\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/leah_fmod/32/3685_2.png) [@Leah\_FMOD](https://qa.fmod.com/u/Leah_FMOD)
#### Post date: [December 19, 2022, 2:11am UTC](https://qa.fmod.com/t/rhythm-based-action-shooting/19644/2 "2022-12-19T02:11:36Z")

</div>

Hi,

The process of tracking beats in FMOD is handled by timeline callbacks. The [Timeline Callbacks scripting example](https://www.fmod.com/docs/2.02/unity/examples-timeline-callbacks.html) 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`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#fmod_studio_timeline_beat_properties), [`FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#fmod_studio_timeline_marker_properties) and [`FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#fmod_studio_timeline_marker_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()`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#studio_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()`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#studio_eventinstance_setuserdata)

4. Retrieve the user data from within the callback using [`EventInstance.getUserData()`](https://www.fmod.com/docs/2.02/api/studio-api-eventinstance.html#studio_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!
