{"id":6411,"date":"2025-10-06T23:55:35","date_gmt":"2025-10-06T14:55:35","guid":{"rendered":"https:\/\/blog.criware.com\/?p=6411"},"modified":"2025-10-06T23:58:15","modified_gmt":"2025-10-06T14:58:15","slug":"smooth-musical-transitions-between-levels-part-2","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2025\/10\/06\/smooth-musical-transitions-between-levels-part-2\/","title":{"rendered":"Smooth musical transitions between levels [Part 2]"},"content":{"rendered":"<p>This is the last part of our tutorial in which we see how to play an intermediary music when switching between 2 main songs. In the <a href=\"https:\/\/blog.criware.com\/index.php\/2025\/10\/02\/smooth-musical-transitions-between-levels\/\">previous post<\/a>, we prepared an ADX Cue Sheet containing our main songs and transition Cues. We added markers to BeatSync tracks to enable smooth jumping between all these Cues. This time, we will import the data authored in AtomCraft into Unreal Engine and implement it in the game with Blueprints.<\/p>\n<h5>Importing the Atom Craft data into UE5<\/h5>\n<p>Let\u2019s first import the binary Cue Sheet we built into our UE5 project.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B1.png\" alt=\"\" width=\"863\" height=\"386\" class=\"alignnone size-full wp-image-6415\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B1.png 863w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B1-300x134.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B1-768x344.png 768w\" sizes=\"auto, (max-width: 863px) 100vw, 863px\" \/><\/p>\n<p>In the dialogs that appear when importing the acf file, choose Yes both times.<br \/>\nThis will automatically set the acf file for your project.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B2.png\" alt=\"\" width=\"465\" height=\"185\" class=\"alignnone size-full wp-image-6417\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B2.png 465w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B2-300x119.png 300w\" sizes=\"auto, (max-width: 465px) 100vw, 465px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B3.png\" alt=\"\" width=\"595\" height=\"228\" class=\"alignnone size-full wp-image-6418\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B3.png 595w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B3-300x115.png 300w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/p>\n<p>You can then open the acb file (i.e., your Cue Sheet) to check that the Cues play correctly.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B4.png\" alt=\"\" width=\"1147\" height=\"594\" class=\"alignnone size-full wp-image-6419\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B4.png 1147w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B4-300x155.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B4-1024x530.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B4-768x398.png 768w\" sizes=\"auto, (max-width: 1147px) 100vw, 1147px\" \/><\/p>\n<h5>Playing BGM from the Level Blueprint<\/h5>\n<p>For the moment, we will simply create two rooms and make the background music switch when moving between them.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B5.png\" alt=\"\" width=\"1400\" height=\"717\" class=\"alignnone size-full wp-image-6421\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B5.png 1400w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B5-300x154.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B5-1024x524.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B5-768x393.png 768w\" sizes=\"auto, (max-width: 1400px) 100vw, 1400px\" \/><\/p>\n<p>Let\u2019s open the Level Blueprint.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B6.png\" alt=\"\" width=\"812\" height=\"488\" class=\"alignnone size-full wp-image-6422\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B6.png 812w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B6-300x180.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B6-768x462.png 768w\" sizes=\"auto, (max-width: 812px) 100vw, 812px\" \/><\/p>\n<p>We will use a <strong>Spawn Sound 2D<\/strong> node when the <strong>BeginPlay<\/strong> event is triggered to play the BGM.<br \/>\n(The <strong>Set View Target with Blend<\/strong> node shown in the screenshot is only here for the camera.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B7.png\" alt=\"\" width=\"1118\" height=\"426\" class=\"alignnone size-full wp-image-6424\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B7.png 1118w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B7-300x114.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B7-1024x390.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B7-768x293.png 768w\" sizes=\"auto, (max-width: 1118px) 100vw, 1118px\" \/><\/p>\n<p>Right-click the input pin of the Spawn Sound 2D node and select <strong>Promote to Variable<\/strong> to create a variable.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B8_X.png\" alt=\"\" width=\"1117\" height=\"424\" class=\"alignnone size-full wp-image-6425\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B8_X.png 1117w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B8_X-300x114.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B8_X-1024x389.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B8_X-768x292.png 768w\" sizes=\"auto, (max-width: 1117px) 100vw, 1117px\" \/><\/p>\n<p>Name it \u201cBGM.\u201d<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B9_X.png\" alt=\"\" width=\"1228\" height=\"435\" class=\"alignnone size-full wp-image-6426\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B9_X.png 1228w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B9_X-300x106.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B9_X-1024x363.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B9_X-768x272.png 768w\" sizes=\"auto, (max-width: 1228px) 100vw, 1228px\" \/><\/p>\n<p>Compile the graph, then set the default Cue for the variable in the Details panel.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B10_X.png\" alt=\"\" width=\"872\" height=\"659\" class=\"alignnone size-full wp-image-6427\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B10_X.png 872w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B10_X-300x227.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B10_X-768x580.png 768w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><\/p>\n<p>Expand the <strong>Spawn Sound 2D<\/strong> node.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B11_X.png\" alt=\"\" width=\"510\" height=\"291\" class=\"alignnone size-full wp-image-6428\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B11_X.png 510w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B11_X-300x171.png 300w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/p>\n<p>Uncheck <strong>Auto Destroy<\/strong>. Normally, an Atom component spawned by <strong>Spawn Sound 2D<\/strong> will automatically be destroyed once the playback ends. However, in this case, we want to reuse it later to play a different Cue, so we disable its automatic destruction.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B12_X.png\" alt=\"\" width=\"525\" height=\"414\" class=\"alignnone size-full wp-image-6429\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B12_X.png 525w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B12_X-300x237.png 300w\" sizes=\"auto, (max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>We can now run the game to confirm that the BGM plays.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B13.png\" alt=\"\" width=\"517\" height=\"335\" class=\"alignnone size-full wp-image-6430\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B13.png 1035w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B13-300x194.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B13-1024x662.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B13-768x496.png 768w\" sizes=\"auto, (max-width: 517px) 100vw, 517px\" \/><\/p>\n<h5>Monitoring Tempo and Triggering Events<\/h5>\n<p>Let\u2019s add a new variable to store which room the player is currently. We will use an Int named <strong>CurrentRoom<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B14.png\" alt=\"\" width=\"396\" height=\"178\" class=\"alignnone size-full wp-image-6431\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B14.png 396w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B14-300x135.png 300w\" sizes=\"auto, (max-width: 396px) 100vw, 396px\" \/><\/p>\n<p>We then add two <strong>Box Trigger<\/strong> volumes to the level. Resize them, so that each covers one the rooms.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15.png\" alt=\"\" width=\"1199\" height=\"665\" class=\"alignnone size-full wp-image-6432\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15.png 1199w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15-300x166.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15-1024x568.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15-768x426.png 768w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B15-800x445.png 800w\" sizes=\"auto, (max-width: 1199px) 100vw, 1199px\" \/><\/p>\n<p>With one of the volumes selected, return to the Level Blueprint and add an <strong>On Actor Begin Overlap<\/strong> event.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B16.png\" alt=\"\" width=\"613\" height=\"485\" class=\"alignnone size-full wp-image-6433\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B16.png 613w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B16-300x237.png 300w\" sizes=\"auto, (max-width: 613px) 100vw, 613px\" \/><\/p>\n<p>Use a <strong>Branch<\/strong> node to check if the overlapping actor is the <strong>Player Character<\/strong>.<br \/>\nThis will allow us to detect when the player moves between rooms. Repeat this setup for the second volume.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B17.png\" alt=\"\" width=\"787\" height=\"657\" class=\"alignnone size-full wp-image-6434\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B17.png 787w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B17-300x250.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B17-768x641.png 768w\" sizes=\"auto, (max-width: 787px) 100vw, 787px\" \/><\/p>\n<p>Every time the player moves to another room, we will update the <strong>CurrentRoom<\/strong> variable.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B18.png\" alt=\"\" width=\"956\" height=\"656\" class=\"alignnone size-full wp-image-6435\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B18.png 956w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B18-300x206.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B18-768x527.png 768w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B18-130x90.png 130w\" sizes=\"auto, (max-width: 956px) 100vw, 956px\" \/><\/p>\n<p>Return to the processing of the <strong>BeginPlay<\/strong> event.<br \/>\nRight-click the blue output pin of the <strong>Spawn Sound 2D<\/strong> node and select <strong>Promote to Variable<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B19_X.png\" alt=\"\" width=\"679\" height=\"401\" class=\"alignnone size-full wp-image-6436\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B19_X.png 679w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B19_X-300x177.png 300w\" sizes=\"auto, (max-width: 679px) 100vw, 679px\" \/><\/p>\n<p>Name this variable Atom BGM. From its output pin, drag out a line and choose <strong>Assign On Atom Sound Cue Beat Sync<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B20_X.png\" alt=\"\" width=\"994\" height=\"543\" class=\"alignnone size-full wp-image-6437\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B20_X.png 994w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B20_X-300x164.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B20_X-768x420.png 768w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><\/p>\n<p>This will place both a <strong>Bind Event to On Atom Sound Cue Beat Sync<\/strong> node and an event node (named <strong>OnBeat<\/strong>).<br \/>\nThis event will be triggered in sync with the BGM\u2019s beat.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B21_X.png\" alt=\"\" width=\"922\" height=\"509\" class=\"alignnone size-full wp-image-6438\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B21_X.png 922w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B21_X-300x166.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B21_X-768x424.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/p>\n<p>In order to test it, you can connect a <strong>Print String<\/strong> node to the <strong>OnBeat<\/strong> event to display a text for each beat.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B22.png\" alt=\"\" width=\"974\" height=\"635\" class=\"alignnone size-full wp-image-6439\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B22.png 974w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B22-300x196.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B22-768x501.png 768w\" sizes=\"auto, (max-width: 974px) 100vw, 974px\" \/><\/p>\n<p>When you play the game, you will see the beat count progress within each measure displayed in the top-left corner.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B23.png\" alt=\"\" width=\"214\" height=\"144\" class=\"alignnone size-full wp-image-6440\" \/><\/p>\n<h5>Playing a Transition Phrase and Switching the BGM<\/h5>\n<p>Let\u2019s add another Int variable named <strong>CurrentBGM<\/strong> to store the index of the BGM that is currently playing.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B24.png\" alt=\"\" width=\"400\" height=\"272\" class=\"alignnone size-full wp-image-6441\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B24.png 400w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B24-300x204.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>We want the transition phrase to start at a good time musically (i.e., the beginning of a measure) so we monitor the <strong>Beat Count<\/strong>, and when it is back to 0, we check whether we need to switch the BGM.<br \/>\nA <strong>Branch<\/strong> node is used to check whether the current BGM matches the player\u2019s current room.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B25_X.png\" alt=\"\" width=\"1441\" height=\"671\" class=\"alignnone size-full wp-image-6442\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B25_X.png 1441w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B25_X-300x140.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B25_X-1024x477.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B25_X-768x358.png 768w\" sizes=\"auto, (max-width: 1441px) 100vw, 1441px\" \/><\/p>\n<p>We create a new variable to store all BGM Cues together.<br \/>\nWe set the type to <strong>Atom Sound Cue<\/strong>, then click the icon next to Variable Type to make it an <strong>array<\/strong>. Call it <strong>BGMList<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B26.png\" alt=\"\" width=\"661\" height=\"516\" class=\"alignnone size-full wp-image-6443\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B26.png 661w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B26-300x234.png 300w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/p>\n<p>Compile the Blueprint, then add the Cues to the array in the Default Value section.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B27.png\" alt=\"\" width=\"636\" height=\"905\" class=\"alignnone size-full wp-image-6444\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B27.png 636w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B27-211x300.png 211w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/p>\n<p>If the current BGM and room do not match, we need to switch to a different BGM Cue. In that case, we specify a transition phrase (either ADX_BGM_AT or ADX_BGM_BT). We use a <strong>Select<\/strong> node to specify the index in the <strong>BGMList<\/strong> based on the value of <strong>CurrentBGM<\/strong>.(Even if the node\u2019s logic looks a bit confusing at first, try replicating it as shown here.<br \/>\nYou will get a clearer idea once you see it in action!)<\/p>\n<p>After that, we assign the <strong>CurrentRoom<\/strong> value to <strong>CurrentBGM<\/strong> to make them match.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B28_X.png\" alt=\"\" width=\"1470\" height=\"739\" class=\"alignnone size-full wp-image-6445\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B28_X.png 1470w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B28_X-300x151.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B28_X-1024x515.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B28_X-768x386.png 768w\" sizes=\"auto, (max-width: 1470px) 100vw, 1470px\" \/><\/p>\n<p>Since we want to start the next room\u2019s BGM only after the transition phrase has stopped, let\u2019s place a Bind Event to <strong>On Atom Sound Play State Changed<\/strong> node to get notified when the playback state changes.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B29_X.png\" alt=\"\" width=\"1252\" height=\"601\" class=\"alignnone size-full wp-image-6446\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B29_X.png 1252w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B29_X-300x144.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B29_X-1024x492.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B29_X-768x369.png 768w\" sizes=\"auto, (max-width: 1252px) 100vw, 1252px\" \/><\/p>\n<p>The event triggered by <strong>Bind Event<\/strong> to <strong>On Atom Sound Play State Changed<\/strong> provides the current playback state.<br \/>\nWe can add logic based on the playback state by connecting the event output pin to a <strong>Switch<\/strong> node.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B30_X.png\" alt=\"\" width=\"1352\" height=\"816\" class=\"alignnone size-full wp-image-6447\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B30_X.png 1352w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B30_X-300x181.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B30_X-1024x618.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B30_X-768x464.png 768w\" sizes=\"auto, (max-width: 1352px) 100vw, 1352px\" \/><\/p>\n<p>Here, we want to continue the process only when the state is <strong>Stopped<\/strong> (i.e., when the playback ends).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B31_X.png\" alt=\"\" width=\"1410\" height=\"752\" class=\"alignnone size-full wp-image-6448\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B31_X.png 1410w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B31_X-300x160.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B31_X-1024x546.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B31_X-768x410.png 768w\" sizes=\"auto, (max-width: 1410px) 100vw, 1410px\" \/><\/p>\n<p>Because this event is triggered every time the playback state changes, make sure to temporarily disable it after the process completes.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B32_X.png\" alt=\"\" width=\"1351\" height=\"702\" class=\"alignnone size-full wp-image-6449\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B32_X.png 1351w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B32_X-300x156.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B32_X-1024x532.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/10\/B32_X-768x399.png 768w\" sizes=\"auto, (max-width: 1351px) 100vw, 1351px\" \/><\/p>\n<p>That\u2019s it: now, when the player moves between rooms, a transition phrase will play before switching to the new room\u2019s BGM. When the next BGM can be reasonably predicted, you can also consider using features such as <strong>Block Playback<\/strong> or <strong>REACT<\/strong>. We will talk about this in future tutorials!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the last part of our tutorial in which we see how to play an intermediary music when switching<\/p>\n","protected":false},"author":2,"featured_media":6414,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[5,7,22],"tags":[],"class_list":["post-6411","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-adx","category-tutorials","category-unreal-engine"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/6411","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=6411"}],"version-history":[{"count":8,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/6411\/revisions"}],"predecessor-version":[{"id":6453,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/6411\/revisions\/6453"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/6414"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=6411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=6411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=6411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}