CRIWARE Unity Plugin Manual  Last Updated: 2024-07-12
Sound control across scenes

Description of the sample

Overview

You may want to control sounds across scenes, for example to play music or to cross-fade it during level changes.
This sample describes the script and the settings used to control sounds across scenes.

cri4u_samples_criatom_script03_main.png

Operations

Be sure to start at "TitleScene".
  • change scene button in the top-right corner of the screen
    Toggles between TitleScene and GameScene.

Scene information


Middleware CRI ADX (CRI Atom)
Sample Script sample: Sound control across scenes
Location /CRIWARE/SDK/unity/samples/UnityProject/Assets/Scenes/criatom/script/ScriptSample03_OverSceneSound
Scene files ScriptSample03_TitleScene.unity
ScriptSample03_GameScene.unity
Original ADX data Data: Simple cross-fading of music


Description of the program

This sample project controls sounds across scenes.
First, create the sound control script for CRI-related objects and applications in the initial scene. Then, configure the script so that it will not be disposed of but continue to be used when the initial scene is finished.
The ScriptSample03_SoundManager object controls the sounds in the application. A static function, ScriptSample03_SoundManager.PlayCueId(), is called to invoke sound playback from any scene.
This sample plays scene-specific music when each scene is started.
The sound data is configured to cross-fade the music when it is started. This prevents music from being interrupted when scenes are switched. You can also continue to play the same music across scenes.

Configuration to maintain sound-related objects active when scenes are switched

You must configure four objects (components) so that they are not destroyed when scenes are switched.
(1) Select the Don't Destroy On Load option of the CriWareLibraryInitializer.

cri4u_samples_criatom_script03_initializer.png

(2) Select the Don't Destroy On Load option of the CriWareErrorHandler.

cri4u_samples_criatom_script03_error_handler.png

(3) Select the Don't Destroy On Load option of the CRIWARE ojbect (Cri Atom).

cri4u_samples_criatom_script03_criware.png

(4) When the ScriptSample03_SoundManager script is Awake, execute GameObject.DontDestroyOnLoad(this.gameObject).
(5) Add some code to prevent multiple generations when the ScriptSample03_SoundManager script is Awake (details are described below).

Following these steps, you can maintain the CRI-related objects as well as ScriptSample03_SoundManager.cs active when scenes are switched.
Step (5) prevents ScriptSample03_SoundManager.cs from being generated again when the first scene is selected again.
The CRIWARE Library Initializer, CRIWARE Error Handler, and CRI Atom are also prevented from being created again.

Sample implementation of the ScriptSample03_SoundManager script

The SoundManager script needs the implementation of steps (4) and (5) above. Let's take this sample as an example.
GameObject.DontDestroyOnLoad(this.gameObject) represents the implementation of step (4).
GameObject.Destroy(this) based on the isAwaked flag represents the implementation of step (5).

using System.Collections;
using System.Collections.Generic;
public class ScriptSample03_SoundManager : MonoBehaviour {
/* ACB file name (CueSheet name) */
public string cueSheetName = "CueSheet_0";
private CriAtomSource atomSourceMusic;
static private ScriptSample03_SoundManager instance = null;
void Awake ()
{
if (instance != null) {
/*
* To prevent multiple generation, the SoundManager created later destroys itself.
* However, the GameObject with the SoundManager as a component is not destroyed.
* Therefore, in the hierarchy of Unity Editor, multiple GameObjects of the same name exist.
*/
GameObject.Destroy(this);
return;
}
/* Create the CriAtomSource for BGM. */
atomSourceMusic = gameObject.AddComponent<CriAtomSource> ();
atomSourceMusic.cueSheet = cueSheetName;
/* Do not destroy the SoundManger when scenes are switched. */
GameObject.DontDestroyOnLoad(this.gameObject);
instance = this;
}
static public void PlayCueId(int cueId){
instance.atomSourceMusic.Play(cueId);
}
void OnDestroy(){
if (instance == this) {
instance = null;
}
}
}

Two identical objects are shown at Hierarchy

When you return from ScriptSample03_GameScene to ScriptSample03_TitleScene after executing this sample, you will notice that two instances of some objects are shown in the Hierarchy window.

cri4u_samples_criatom_script03_double_object.png

Please ignore them. They will cause no harm.
When the multiple generation of each object is checked, the Component itself is destroyed, but its parent game object is not destroyed, which causes this phenomenon.
The Inspector shows that the second game object is empty. This empty object is later destroyed when scenes are switched again. Therefore, three or more identical objects will not be created.
To prevent empty objects from being displayed, the parent game object must be destroyed when multiple generations is checked. However, it is dangerous, because this may destroy a parent game object to which other components are connected.
A recommended implementation is to allow only one parent game object to exist in order to eliminate the necessity for checking multiple generation for each component.

How to enable the start of the script at any scene

This sample focuses on the destruction of components at a scene change and the checking of multiple generations. Therefore, it must start at ScriptSample03_TitleScene.
The " Can start from any scene " sample describes how to enable the start of the script at any scene.

Description of the script for each game scene

This sample requests sound playback from a scene-specific script.
ScriptSample03_SoundManager.cs exists across the scenes, and a static function, SoundManager.PlayCueId(), is defined. Thus, you can play sounds from the script for any scene.
The scene-specific scripts for this sample are very simple. They just start to play music when the scene is started.

Script file Scripts/ScriptSample03_TitleScene.cs
using System.Collections;
public class ScriptSample03_TitleScene : MonoBehaviour {
private int SceneMusicCueId = 1;
private string nextSceneName = "ScriptSample03_GameScene";
/* Called before the first Update(). */
void Start () {
/* Play BGM. */
ScriptSample03_SoundManager.PlayCueId(SceneMusicCueId);
}
/* Show and control the scene-switching GUI. */
void OnGUI(){
if (Scene_00_SampleList.ShowList == true) {
return;
}
/* Set UI skin. */
GUI.skin = Scene_00_SampleList.uiSkin;
Scene_00_GUI.BeginGui("01/SampleMain");
if (Scene_00_GUI.Button(new Rect(Screen.width-250,200,150,150), "change\nscene")) {
Application.LoadLevel(nextSceneName);
}
Scene_00_GUI.EndGui();
}
}

Difference with the advanced sample

The difference with " [CriAtom] Switching scenes without interrupting the BGM " in [CriAtom] Advanced samples of CRI ADX is described below.
Both samples are identical in that they play sounds across scenes.
This sample uses an application creation script, ScriptSample03_SoundManager. Meanwhile, " [CriAtom] Switching scenes without interrupting the BGM " configures the Hierarchy so that a CRI Atom Source can be used continuously without scripting.
You can use either method, depending on what works better for you.