As shown above, when the gameover, the music should stop
But the code"stop (FMOD.Studio.STOP_MODE.IMMEDIATE)"doesn’t work
Hi,
What version of the FMOD integration are you using?
Could you please add an FMOD_RESULT to the musicEventInstance.stop
and .release
calls and share their results?
Most FMOD functions will return a result
which can be very useful for debugging unexpected behavior.
I’m using FMOD Studioo2.02.21
And for the intergration. I remember I download it on Unity Asset store
Thanks for your suggestion
It’s my first time to use FMOD
To be honest,I don’t know how to do even though you gave very clear instruction
I only know I should enum the result,right?
You can check the integration version in the About FMOD
option:
Could you please try adding the following to your script:
print("StopMusic");
var result = musicEventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
result = musicEventInstance.release();
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
This will log the error message if the stop()
function does not return the FMOD.RESULT.OK
.
Hope this helps!
I tried the code,
It says" ERR_INVALID_HANDLE"
And I’m using Version: 2.02.21
That indicates that musicEventInstance
is no longer connected to a valid instance.
Would it be possible to get the full code you’re using to play and stop the event?
And I forgot to tell you there’re another two errors"Found more than one FMOD Events instance " and"Found more than one Audio Manager"
The audio manager script:
private void Awake()
{
if(instance != null)
{
Debug.LogError("Found more than one Audio Manager");
}
instance = this;
}
The FMOD Events script which has error is as same as audio manger’s
Audio Manager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMODUnity;
using FMOD.Studio;
public class AudioManager : MonoBehaviour
{
public static AudioManager instance{get;private set;}
private List<EventInstance> eventInstances;
private EventInstance musicEventInstance;
private void InitializeMusic(EventReference musicEventReference)
{
musicEventInstance = CreateInstance(musicEventReference);
musicEventInstance.start();
}
public EventInstance CreateInstance(EventReference eventReference)
{
EventInstance eventInstance = RuntimeManager.CreateInstance(eventReference);
return eventInstance;
}
private void Start()
{
InitializeMusic(FMODEvents.instance.music);
DontDestroyOnLoad(GameObject.Find("AudioManager"));
}
private void Awake()
{
if(instance != null)
{
Debug.LogError("Found more than one Audio Manager");
}
instance = this;
}
public void PlayOneShot(EventReference sound,Vector3 worldPos)
{
RuntimeManager.PlayOneShot(sound,worldPos);
}
}
FMOD Events:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMODUnity;
public class FMODEvents : MonoBehaviour
{
[field:Header("Coin SFX")]
[field:SerializeField] public EventReference coinCollected{get;private set;}
[field:Header("Shoot SFX")]
[field:SerializeField] public EventReference playerShoot{get;private set;}
[field:Header("Death SFX")]
[field:SerializeField] public EventReference playerDeath{get;private set;}
[field:Header("Door SFX")]
[field:SerializeField] public EventReference doorOpen{get;private set;}
[field:Header("Enemy SFX")]
[field:SerializeField] public EventReference enemyHit{get;private set;}
[field:Header("Music")]
[field:SerializeField] public EventReference music{get;private set;}
public static FMODEvents instance{get;private set;}
private void Awake()
{
if(instance != null)
{
Debug.LogError("Found more than one FMOD Events instance ");
}
instance = this;
}
}
The place I want to stop the music event is when the "Gameover"screen show up.
if (collision.gameObject.CompareTag("Enemy") && canMove)
{
HitpointsHeart[HitPoints - 1].GetComponent<Animator>().enabled = true;
AudioManager.instance.PlayOneShot(FMODEvents.instance.enemyHit,this.transform.position);
HitPoints--;
if (HitPoints <= 0)
{
HitPoints = 0;
AudioManager.instance.PlayOneShot(FMODEvents.instance.playerDeath,this.transform.position);
Debug.Log("Game_Over");
Invoke("Gameover", 1.3f);
print("StopMusic");
var result = musicEventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
result = musicEventInstance.release();
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
}
// Prevent further movement temporarily
canMove = false;
// Apply hit effect immediately
ApplyHitEffect(collision);
// Start a coroutine to enable movement after a delay
StartCoroutine(EnableMovementAfterDelay());
}
Thank you for the code.
You can check an event instance is valid before interacting with it by using: EventInstance::isValid.
It could be added here:
if (HitPoints <= 0)
{
HitPoints = 0;
AudioManager.instance.PlayOneShot(FMODEvents.instance.playerDeath,this.transform.position);
Debug.Log("Game_Over");
Invoke("Gameover", 1.3f);
if (musicEventInstance.isValid())
{
print("StopMusic");
var result = musicEventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
result = musicEventInstance.release();
if (result != FMOD.RESULT.OK)
{
Debug.Log($"Failed to stop event with result: {result}");
}
}
else
{
Debug.Log("musicEventInstance is not valid");
}
}
How is the musicEventInstance
being set in the class that contains this function? I can see it being set in the AudioManager
, however, that class does not contain this if()
function.
Losing the reference to the valid instance may be caused by Unity’s shallow copying.
I was able to stop the musicEventInstance
in the AudioManager
as that instance is a member variable of that class.