{"id":2568,"date":"2019-10-16T16:10:49","date_gmt":"2019-10-16T07:10:49","guid":{"rendered":"https:\/\/blog.criware.com\/?p=2568"},"modified":"2019-10-17T08:30:23","modified_gmt":"2019-10-16T23:30:23","slug":"animating-to-the-beat-with-adx2-and-unity","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2019\/10\/16\/animating-to-the-beat-with-adx2-and-unity\/","title":{"rendered":"Animating to the Beat with ADX2 and Unity"},"content":{"rendered":"<h2 style=\"font-size: 150%; font-weight: bold;\">Introduction<\/h2>\n<p>Virtual worlds work best when all the components work together harmoniously. This is the core of the creative process, as a sound designer\u2019s 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.<\/p>\n<p>This month we will be looking at taking advantage of ADX2\u2019s BeatSync functionality to control 2D sprite animation.<\/p>\n<div style=\"max-width: 800px; margin: 0 auto; margin-bottom: 20px;\">\n<div style=\"width: 800px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-2568-1\" width=\"800\" height=\"450\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/1910_BeatSyncAnimation.mp4?_=1\" \/><a href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/1910_BeatSyncAnimation.mp4\">https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/1910_BeatSyncAnimation.mp4<\/a><\/video><\/div>\n<\/div>\n<div style=\"max-width: 800px; margin: 0 auto; margin-bottom: 20px; text-align:center;\">\n<a style=\"display: inline-block; border: 1px solid #ccc; padding: 20px;\" href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/1910_BeatSync.zip\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1813\" style=\"display: inline-block;\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2018\/06\/zip.png\" alt=\"zip\" width=\"80\" height=\"78\"><br \/>\n1910_BeatSync.zip<\/a><\/p>\n<p><em>This project was created using CRIWARE SDK for Unity V2.99.00 and Unity V2019.1.6f1<\/em>\n<\/div>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Atom Craft<\/h2>\n<p>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 \u2192 New Object \u2192 Create BeatSync Parameter for each Cue and set their BPM in the Inspector to match the tempo of the respective music Cues.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-1.png\" alt=\"17-1\" width=\"905\" height=\"354\" class=\"alignnone size-full wp-image-2573\" style=\" display: block; margin: 0 auto;\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-1.png 905w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-1-300x117.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-1-768x300.png 768w\" sizes=\"auto, (max-width: 905px) 100vw, 905px\" \/><\/p>\n<p>We can further tweak the time signature in the Inspector and set our own custom Beat Pattern if applicable.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-2.png\" alt=\"17-2\" width=\"520\" height=\"170\" class=\"alignnone size-full wp-image-2575\" style=\" display: block; margin: 0 auto;\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-2.png 520w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-2-300x98.png 300w\" sizes=\"auto, (max-width: 520px) 100vw, 520px\" \/><\/p>\n<p>This project is now ready to be built and loaded into Unity.<\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Unity<\/h2>\n<p>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\u2019ve based the following example on controlling the animating of a 2D sprite.<\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Animation<\/h2>\n<p>We only need two states to demonstrate this effect with animation, a \u201cPlayer_Idle\u201d state, and a \u201cPlayer_Dancing\u201d 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.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-3.png\" alt=\"17-3\" width=\"656\" height=\"227\" class=\"alignnone size-full wp-image-2576\" style=\" display: block; margin: 0 auto;\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-3.png 656w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-3-300x104.png 300w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-4.png\" alt=\"17-4\" width=\"598\" height=\"288\" class=\"alignnone size-full wp-image-2577\" style=\" display: block; margin: 0 auto;\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-4.png 598w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/10\/17-4-300x144.png 300w\" sizes=\"auto, (max-width: 598px) 100vw, 598px\" \/><\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Script<\/h2>\n<p>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:<\/p>\n<pre><code class=\"hljs php\">\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing UnityEngine;\r\n\r\npublic class BeatSyncAnimation : MonoBehaviour\r\n{\r\n    private Animator animator;\r\n    private SpriteRenderer sprite;\r\n    private float bpm;\r\n\r\n    void Start()\r\n    {\r\n        animator = gameObject.GetComponent<Animator>();\r\n        sprite = gameObject.GetComponent<SpriteRenderer>();\r\n\r\n        CriAtomExBeatSync.SetCallback(BeatSyncCallback);\r\n    }\r\n\r\n    void BeatSyncCallback(ref CriAtomExBeatSync.Info info)\r\n    {\r\n        animator.Play(\"Player_Dancing\");\r\n\r\n        if (bpm != info.bpm)\r\n        {\r\n            Debug.Log(\"bpm is now :\" + info.bpm);\r\n            bpm = info.bpm;\r\n        }\r\n    }\r\n}\r\n\r\n<\/code>\r\n<\/pre>\n<p>Most of what is happening is being effortlessly taken care of by ADX2. First, we have a callback function which references information from ADX2\u2019s <em>CriAtomExBeatSync<\/em> (which is called every beat). This then instructs the animator to Play the \u201cPlayer_Dancing\u201d 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.<\/p>\n<p>It is worth pointing out that the code which controls playing and stopping of the Cues is only calling <em>CriAtomSource.Play() <\/em>and <em>CriAtomSource.Stop() <\/em>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.<\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Conclusion<\/h2>\n<p>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!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Virtual worlds work best when all the components work together harmoniously. This is the core of the creative process,<\/p>\n","protected":false},"author":2,"featured_media":2585,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[5,7],"tags":[],"class_list":["post-2568","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-adx","category-tutorials"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/2568","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/comments?post=2568"}],"version-history":[{"count":8,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/2568\/revisions"}],"predecessor-version":[{"id":2586,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/2568\/revisions\/2586"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/2585"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=2568"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=2568"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=2568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}