{"id":2599,"date":"2019-11-19T17:04:41","date_gmt":"2019-11-19T08:04:41","guid":{"rendered":"https:\/\/blog.criware.com\/?p=2599"},"modified":"2019-11-19T17:08:44","modified_gmt":"2019-11-19T08:08:44","slug":"controlling-gamepad-vibration-with-sound-in-unity-using-adx2","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2019\/11\/19\/controlling-gamepad-vibration-with-sound-in-unity-using-adx2\/","title":{"rendered":"Controlling Gamepad Vibration with Sound in Unity using ADX2"},"content":{"rendered":"<h2 style=\"font-size: 150%; font-weight: bold;\">Introduction<\/h2>\n<p>Being able to control gameplay with audio information is a great way to take out some of the manual work needed to create a complex game system. Fortunately, ADX2 is loaded with easy to use features for achieving bi-directional control between game engine and audio engine. This blog will look at using ADX2\u2019s analysis capabilities to directly control the level of shake in an Xbox 360 controller.<\/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-2599-1\" width=\"800\" height=\"450\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/1911_GamepadVibration.mp4?_=1\" \/><a href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/1911_GamepadVibration.mp4\">https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/1911_GamepadVibration.mp4<\/a><\/video><\/div>\n<\/div>\n<p><!-- download start --><\/p>\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\/11\/1911_GamepadVibration_AtomCraftProject.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 \/>\n1911_GamepadVibration_AtomCraftProject.zip<\/a>\n<\/div>\n<p><!-- download stop --><\/p>\n<p><em>This project was created using CRIWARE SDK for Unity V2.99.00 and Unity V2019.2.10f1 <\/em><\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Atom Craft<\/h2>\n<p>For our system to work, we need some sort of sound (such as music), and a bus where we can send data to be analysed later.<\/p>\n<p>Starting with the bus:<\/p>\n<ul>\n<li>In the Project Tree &#8211; navigate to <strong>DspBusSetting_0<\/strong><\/li>\n<li>Create a new bus, and name it \u201cBeatBus\u201d<\/li>\n<li>In the Project Tree &#8211; navigate to <strong>BusMap_Default<\/strong><\/li>\n<li>Set DspBusName1 to BeatBus<\/li>\n<\/ul>\n<p>Don\u2019t worry about sending any signal from the BeatBus to MasterOut, this bus is only for analysis. Also, make a note of the newly created bus\u2019s name, as it will be referenced to in Unity.<\/p>\n<p>Then, for the all-important audio data:<\/p>\n<ul>\n<li>Create a new <strong>Polyphonic Cue<\/strong>, and name it \u201cCue_Music\u201d<\/li>\n<li>Add Bass and Drum Waveform Materials to separate Tracks in Cue_Music<\/li>\n<li>In the Inspector &#8211; enable BusSend1 for Drum Track<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"max-width: 800px;\n    display: block;\n    margin: 0 auto;\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/21-1.png\" alt=\"21-1\" width=\"1065\" height=\"431\" class=\"alignnone size-full wp-image-2605\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/21-1.png 1065w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/21-1-300x121.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/21-1-768x311.png 768w, https:\/\/blog.criware.com\/wp-content\/uploads\/2019\/11\/21-1-1024x414.png 1024w\" sizes=\"auto, (max-width: 1065px) 100vw, 1065px\" \/><\/p>\n<p>This should give us everything we need to test with, so we can now Build the CueSheet Binary (With Unity Assets set to enabled in the Additional Outputs settings) and load up Unity.<\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Unity<\/h2>\n<p>To make controller input easier to manage, we can download a Unity plugin called XInputDotNet. This will give us some handy boilerplate to make controller setup very simple. This single script below will handle all our controller management and audio analysis.<\/p>\n<p><!-- code start --><\/p>\n<pre>\r\n<code class=\"hljs php\">\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing UnityEngine;\r\nusing XInputDotNetPure;\r\n\r\npublic class GamepadShaker : MonoBehaviour\r\n{\r\n    bool playerIndexSet = false;\r\n    PlayerIndex playerIndex;\r\n    GamePadState state;\r\n    GamePadState prevState;\r\n\r\n    void Start()\r\n    {\r\n        CriAtom.AttachDspBusSetting(\"DspBusSetting_0\");\r\n        CriAtom.SetBusAnalyzer(true);\r\n    }\r\n\r\n    void Update()\r\n    {\r\n        \/\/ XInput boilerplate to find and assign connected controller\r\n        if (!playerIndexSet || !prevState.IsConnected) {\r\n            for (int i = 0; i < 4; ++i)\r\n            {\r\n                PlayerIndex testPlayerIndex = (PlayerIndex)i;\r\n                GamePadState testState = GamePad.GetState(testPlayerIndex);\r\n                if (testState.IsConnected)\r\n                {\r\n                    Debug.Log(string.Format(\"GamePad found {0}\", testPlayerIndex));\r\n                    playerIndex = testPlayerIndex;\r\n                    playerIndexSet = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        \/\/ Analyze the amplitude of the bus, and vibrate controller accordingly\r\n        CriAtomExAsr.BusAnalyzerInfo busInfo = CriAtom.GetBusAnalyzerInfo(\"BeatBus\");\r\n        float vibrationIntensity = busInfo.peakLevels[0];\r\n        GamePad.SetVibration(playerIndex, vibrationIntensity, vibrationIntensity);\r\n    }\r\n\r\n    private void OnDestroy()\r\n    {\r\n        CriAtom.DetachDspBusSetting();\r\n        GamePad.SetVibration(playerIndex, 0, 0);\r\n    }\r\n}\r\n\r\n<\/code>\r\n<\/pre>\n<p><!-- code end --><\/p>\n<p>Most of the above is copy-pasted boilerplate from the XInputDotNet plugin and simply deals with ensuring that the controller is connected and correctly assigned. The integral parts relating to what we are trying to achieve have been highlighted.<\/p>\n<p>First off, in the <em>Start<\/em> function, we Attach our DSP bus and enable the analyser feature for our analyser to work. Next, in the <em>Update<\/em> function:<\/p>\n<ul>\n<li>We create a variable called \u201cbusInfo\u201d and tell it to get the analyser information from the bus that we created in Atom Craft (BeatBus).<\/li>\n<li>Then we create another variable called \u201cvibrationIntensity\u201d, which gets the peak amplitude in real-time from our bus (the square brackets specify 0 - i.e. the left channel)<\/li>\n<li>Finally, the <em>SetVibration<\/em> function sets the current controller\u2019s (playerIndex) vibration for the left and right motors of the controller to our vibrationIntensity.<\/li>\n<\/ul>\n<p>We should also make use of an <em>OnDestroy<\/em> function to do some clean-up, which will stop the controller from vibrating if the application is terminated.<\/p>\n<p>Since the kick drum used in the example above is monophonic, it\u2019s fine to use either left or right channel. However, using the above method, we could easily control the left motor with left channel data and right mother with right channel data.<\/p>\n<h2 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Conclusion<\/h2>\n<p>It may not be the most efficient method of adjusting controller vibration, but it\u2019s a fun way of getting some very direct control between the data generated by our sound and our game engine. It can also be handy for prototyping ideas before a more robust method is implemented.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Being able to control gameplay with audio information is a great way to take out some of the manual<\/p>\n","protected":false},"author":2,"featured_media":2613,"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-2599","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\/2599","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=2599"}],"version-history":[{"count":11,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/2599\/revisions"}],"predecessor-version":[{"id":2616,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/2599\/revisions\/2616"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/2613"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=2599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=2599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=2599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}