Events Not Persisting Through Scene Changes

I’m using Unity 5.1.2f1 with the 1.06.10 FMOD integration. I’ve got an issue where I want to have a crowd sound respond to the game score using start() on the appropriate sound event each time the score changes; however, in our game, the scene resets every time the score changes. Originally I told the script controlling the crowd reactions to DontDestroyOnLoad so they wouldn’t get cut off when the scene changes, but if I do this, the events won’t respond to the .start() method any time after the scene reloads for the first time (possibly because they are initialized in Unity’s void Start() call which doesn’t get called again). However, when I do reload the crowd objects on every scene, the sounds get interrupted on scene changes. Is there a way to make the events keep playing through scene changes without using DontDestroyOnLoad?

Here’s my script for thoroughness:

using UnityEngine;
using System.Collections;
using FMOD.Studio;

public class CrowdSound : MonoBehaviour {

public Transform playerOneSide;
public Transform playerTwoSide;

static FMOD.Studio.EventInstance crowdOneCheer;
static FMOD.Studio.ParameterInstance playerOneCheer;

static FMOD.Studio.EventInstance crowdOneBoo;
static FMOD.Studio.ParameterInstance playerOneBoo;

static FMOD.Studio.EventInstance crowdOneGasp;
static FMOD.Studio.ParameterInstance playerOneGasp;

static FMOD.Studio.EventInstance crowdTwoCheer;
static FMOD.Studio.ParameterInstance playerTwoCheer;

static FMOD.Studio.EventInstance crowdTwoBoo;
static FMOD.Studio.ParameterInstance playerTwoBoo;

static FMOD.Studio.EventInstance crowdTwoGasp;
static FMOD.Studio.ParameterInstance playerTwoGasp;

int newp1score = ScoreManager.scoreOne;
int oldp1score = ScoreManager.scoreOne;
int newp2score = ScoreManager.scoreTwo;
int oldp2score = ScoreManager.scoreTwo;

// Use this for initialization
void Start () {

	// P1 CrowdCheer Setup
	crowdOneCheer = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdCheer");
	if(crowdOneCheer.getParameter("Player", out playerOneCheer) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}

	var attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerOneSide.position);
	crowdOneCheer.set3DAttributes(attributes);

	playerOneCheer.setValue(1);

	// P2 CrowdCheer Setup
	crowdTwoCheer = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdCheer");
	if(crowdTwoCheer.getParameter("Player", out playerTwoCheer) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}
	
	attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerTwoSide.position);
	crowdTwoCheer.set3DAttributes(attributes);

	playerTwoCheer.setValue(2);

	// P1 CrowdBoo Setup
	crowdOneBoo = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdBoo");
	if(crowdOneBoo.getParameter("Player", out playerOneBoo) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}
	
	attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerOneSide.position);
	crowdOneBoo.set3DAttributes(attributes);

	playerOneBoo.setValue(1);

	// P2 CrowdBoo Setup
	crowdTwoBoo = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdBoo");
	if(crowdTwoBoo.getParameter("Player", out playerTwoBoo) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}
	
	attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerTwoSide.position);
	crowdTwoBoo.set3DAttributes(attributes);

	playerTwoBoo.setValue(2);

	// P1 CrowdGasp Setup
	crowdOneGasp = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdGasp");
	if(crowdOneGasp.getParameter("Player", out playerOneGasp) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}
	
	attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerOneSide.position);
	crowdOneGasp.set3DAttributes(attributes);

	playerOneGasp.setValue(1);

	// P2 CrowdGasp Setup
	crowdTwoGasp = FMOD_StudioSystem.instance.GetEvent("event:/Ambience/CrowdGasp");
	if(crowdTwoGasp.getParameter("Player", out playerTwoGasp) != FMOD.RESULT.OK)
	{
		Debug.LogError("Player param not found");
		return;
	}
	
	attributes = FMOD.Studio.UnityUtil.to3DAttributes(playerTwoSide.position);
	crowdTwoGasp.set3DAttributes(attributes);

	playerTwoGasp.setValue(2);


	//Debug.Log (playerOneCrowd != null);
}

// Update is called once per frame
void Update () {
	newp1score = ScoreManager.scoreOne;
	newp2score = ScoreManager.scoreTwo;

	// Cheer after P1 Scores
	if((newp1score > oldp1score) && newp1score < 2)
	{
		PlayCheer (1);
	} else if ((newp1score > oldp1score) && newp1score == 2)
	{
		PlayGasp (1);
		PlayGasp (2);
	}
	
	// Cheer after P2 scores
	if((newp2score > oldp2score) && newp2score < 2)
	{
		PlayCheer (2);
	} else if ((newp2score > oldp2score) && newp2score == 2)
	{
		PlayGasp (1);
		PlayGasp (2);
	}
	
	// Boo after P2 Scores
	if((newp1score < oldp1score))
	{
		PlayBoo (1);
	}
	else if ((newp1score < oldp1score) && newp1score < -1)
	{
		PlayGasp (1);
		PlayGasp (2);
	}
	
	// Cheer after P2 scores
	if((newp2score < oldp2score))
	{
		PlayBoo (2);
	}
	else if ((newp2score < oldp2score) && newp2score < -1)
	{
		PlayGasp (1);
		PlayGasp (2);
	}


	oldp1score = newp1score;
	oldp2score = newp2score;
}

public static void PlayCheer(int player)
{
	if(player == 1)
	{

		crowdOneCheer.start ();
	} else{

		crowdTwoCheer.start ();
	}
}

public static void PlayBoo(int player)
{
	if(player == 1)
	{
		crowdOneBoo.start();
	} else{
		
		crowdTwoBoo.start ();
	}
}

public static void PlayGasp(int player)
{
	if(player == 1)
	{
		crowdOneGasp.start ();
	} else{
		
		crowdTwoGasp.start ();
	}
}

void OnDestroy()
{
	if(crowdOneCheer != null)
	{
		crowdOneCheer.stop(STOP_MODE.ALLOWFADEOUT);
		crowdOneCheer.release();
	}
	if(crowdTwoCheer != null)
	{
		crowdTwoCheer.stop(STOP_MODE.ALLOWFADEOUT);
		crowdTwoCheer.release();
	}
	if(crowdOneBoo != null)
	{
		crowdOneBoo.stop(STOP_MODE.ALLOWFADEOUT);
		crowdOneBoo.release();
	}
	if(crowdTwoBoo != null)
	{
		crowdTwoBoo.stop(STOP_MODE.ALLOWFADEOUT);
		crowdTwoBoo.release();
	}
	if(crowdOneGasp != null)
	{
		crowdOneGasp.stop(STOP_MODE.ALLOWFADEOUT);
		crowdOneGasp.release();
	}
	if(crowdTwoGasp != null)
	{
		crowdTwoGasp.stop(STOP_MODE.ALLOWFADEOUT);
		crowdTwoGasp.release();
	}
}

}

Your solution of DontDestroyOnLoad should work. The EventInstance object will be invalid if the banks are unloaded and then loaded again or the system is shutdown and restarted. This doesn’t happen with the normal integration code, but could happen if you have custom bank loading code.

Could it have anything to do with FMOD_Listener being destroyed on a scene change? Right now I’m just using the normal vanilla integration so as far as I can tell the system isn’t being restarted; plus continuous sounds on DontDestroyOnLoad scripts work fine on scene changes and respond to parameters and everything, it’s just one shot events that I’m trying to .start() after scene changes that were loaded in the previous scene (which sounds like it would point to the EventInstance being invalid)

There’s nothing in vanilla FMOD_Listener that will destroy the system or unload the banks. EventInstance.isValid() will tell you if the handle is still valid. Checking the return code from start() could also give you a hint.