Animating to the Beat with ADX2 and Unity

Introduction

Virtual worlds work best when all the components work together harmoniously. This is the core of the creative process, as a sound designer’s job is to craft sounds which make sense within the context of the game. We can amplify this hard work by between the audio engine and gameplay engine.

This month we will be looking at taking advantage of ADX2’s BeatSync functionality to control 2D sprite animation.


zip
1910_BeatSync.zip

This project was created using CRIWARE SDK for Unity V2.99.00 and Unity V2019.1.6f1

Atom Craft

To get started, we can load some music into Atom Craft and drag the resultant materials onto our CueSheet to create new Polyphonic Cues. For testing purposes, we can create two separate Cues, one for 120 bpm and another for 160 bpm. Finally, we can right-click → New Object → Create BeatSync Parameter for each Cue and set their BPM in the Inspector to match the tempo of the respective music Cues.

17-1

We can further tweak the time signature in the Inspector and set our own custom Beat Pattern if applicable.

17-2

This project is now ready to be built and loaded into Unity.

Unity

After we have performed the initial setup of ADX2 in Unity and loaded the ACB + ACF data, we only need two things to get this system to work: some music with a BeatSync marker to play, and a game object to receive BeatSync data. Since animation can be a fun thing to tie to the rhythm, I’ve based the following example on controlling the animating of a 2D sprite.

Animation

We only need two states to demonstrate this effect with animation, a “Player_Idle” state, and a “Player_Dancing” state. The Idle state can be set to a single frame of animation, and the Dancing state can be 2 frames to convey movement. The states can then be hooked together in the Animator, which will reset the player to their Idle state after the ducking Dance state has played.

17-3

17-4

Script

Now we can load a new script onto our player sprite and set up some code to run on the beat. The code needed is as follows:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BeatSyncAnimation : MonoBehaviour
{
    private Animator animator;
    private SpriteRenderer sprite;
    private float bpm;

    void Start()
    {
        animator = gameObject.GetComponent();
        sprite = gameObject.GetComponent();

        CriAtomExBeatSync.SetCallback(BeatSyncCallback);
    }

    void BeatSyncCallback(ref CriAtomExBeatSync.Info info)
    {
        animator.Play("Player_Dancing");

        if (bpm != info.bpm)
        {
            Debug.Log("bpm is now :" + info.bpm);
            bpm = info.bpm;
        }
    }
}


Most of what is happening is being effortlessly taken care of by ADX2. First, we have a callback function which references information from ADX2’s CriAtomExBeatSync (which is called every beat). This then instructs the animator to Play the “Player_Dancing” animation. Beyond that, we have a small if-statement which logs the current BPM if it is changed. This log is an example of how we can use BeatSync to retrieve other information such as our beat count or time signature, which could be used to further control some other aspect of gameplay.

It is worth pointing out that the code which controls playing and stopping of the Cues is only calling CriAtomSource.Play() and CriAtomSource.Stop() functions. No fancy tracking is being used to check the state of the BeatSync (this is all being controlled internally by the engine). As soon as a Cue containing a BeatSync is stopped, the callback is no longer called because there are no more beats happening to call this function, and thus our animation stops automatically.

Conclusion

Music is ubiquitous in gaming, whether merely as something to set the tone of the game or as a core element of the gameplay loop. Using techniques such as outlined above can help you to make the most of your music, which can lead to a better gameplay experience for the user. Thankfully, ADX2 makes integrating these sorts of features a straight-forward affair!

Leave a Reply

Your email address will not be published. Required fields are marked *