Sorry for the question: How can I do that ? . I mean, i did the FMOD event with Built - in parameters as you can see in the screenshot, but they don´t seem to work with Unity. They work perfectly in FMOD although. And yes, both gameObjects have a rigibody.
Inspector MBox
Inspector Boss
I don´t know how to do that, I´m starting in this world of coding
This:
public void Set3DAttributes(GameObject emitter, FMOD.Studio.EventInstance eventInstance)
{
// Obtener la posición y la orientación del objeto
Vector3 position = transform.position;
Vector3 forward = transform.forward;
Vector3 up = transform.up;
// Crear la estructura de atributos 3D de FMOD
FMOD.ATTRIBUTES_3D attributes = new FMOD.ATTRIBUTES_3D();
attributes.position = FMODUnity.RuntimeUtils.ToFMODVector(position);
attributes.forward = FMODUnity.RuntimeUtils.ToFMODVector(forward);
attributes.up = FMODUnity.RuntimeUtils.ToFMODVector(up);
// Opcional: también puedes configurar la velocidad si es relevante para el doppler
attributes.velocity = FMODUnity.RuntimeUtils.ToFMODVector(Vector3.zero);
// Establecer los atributos 3D en la instancia del evento DesertAmbience
DesertAmbience.set3DAttributes(attributes);
BosqueAmbience.set3DAttributes(attributes);
bossApproachMusic.set3DAttributes(attributes);
bossMusic.set3DAttributes(attributes);
eventInstance.set3DAttributes(attributes);
}
Certainly. Here is the code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMODUnity;
using FMOD.Studio;
using System.Runtime.InteropServices;
public class SoundManager : MonoBehaviour
{
public static SoundManager Instance { get; private set; }
EVENT_CALLBACK dialogueCallback;
private EventInstance musicBox;
private EventInstance bossApproachMusic;
//private EventInstance BossApproachMus;
private bool menuMusicInitialized;
//private EventInstance RecogerGema;
//private EventInstance RecogerCaja;
private List<EventInstance> eventInstances;
private List<StudioEventEmitter> eventEmitters;
public GameObject emitter1; // Asigna en el Inspector o busca por nombre
public GameObject emitter2; // Asigna en el Inspector o busca por nombre
public void Awake()
{
Instance = this;
eventInstances = new List<EventInstance>();
eventEmitters = new List<StudioEventEmitter>();
bossApproachMusic = CreateInstance(FMODEvents.Instance.BossApproachMus);
musicBox = CreateInstance(FMODEvents.Instance.CajaMusica);
//RecogerGema = CreateInstance(FMODEvents.Instance.Recoger);
//RecogerCaja = CreateInstance(FMODEvents.Instance.Recoger);
}
private void Start()
{
UpdateSoundSettings();
dialogueCallback = new EVENT_CALLBACK(DialogueEventCallback);
//Set3DAttributes();
// Configurar los atributos 3D al inicio para cada emisor
Set3DAttributes(emitter1, musicBox);
Set3DAttributes(emitter2, bossApproachMusic);
// Iniciar la reproducción del evento para cada emisor
musicBox.start();
FMOD.RESULT MBoxresult = musicBox.start();
if (MBoxresult != FMOD.RESULT.OK)
{
Debug.Log(MBoxresult);
}
bossApproachMusic.start();
FMOD.RESULT bAMresult = bossApproachMusic.start();
if (bAMresult != FMOD.RESULT.OK)
{
Debug.Log(bAMresult);
}
}
public void Update()
{
// Actualizar los atributos 3D en cada frame para cada emisor
Set3DAttributes(emitter1, musicBox);
Set3DAttributes(emitter2, bossApproachMusic);
// Calcular y establecer parámetros para el primer emisor
float coneAngle1 = CalculateConeAngle(emitter1);
float distance1 = CalculateDistance(emitter1);
float elevationAngle = CalculateElevation(emitter1);
musicBox.setParameterByName("ConeAngle", coneAngle1);
musicBox.setParameterByName("Distance", distance1);
musicBox.setParameterByName("Music Box Floor", elevationAngle);
Debug.Log($"Music Box Elevation (emitter1) is: {elevationAngle}");
// Calcular y establecer parámetros para el segundo emisor
float coneAngle2 = CalculateConeAngle(emitter2);
float distance2 = CalculateDistance(emitter2);
bossApproachMusic.setParameterByName("ConeAngle", coneAngle2);
bossApproachMusic.setParameterByName("Distance", distance2);
Debug.Log($"Music Box distance is : {distance1}");
Debug.Log($"Boss distance is : {distance2}");
Debug.Log($"Music Box angle is : {coneAngle1}");
Debug.Log($"Boss angle is : {coneAngle2}");
}
public void CajadeMusica()
{
// Calcular y establecer parámetros para el primer emisor
float elevationAngle = CalculateElevation(emitter1);
float coneAngle1 = CalculateConeAngle(emitter1);
float distance1 = CalculateDistance(emitter1);
musicBox.setParameterByName("ConeAngle", coneAngle1);
musicBox.setParameterByName("Distance", distance1);
musicBox.setParameterByName("Music Box Floor", elevationAngle);
}
public void BossApproach()
{
Set3DAttributes(emitter2, bossApproachMusic);
// Calcular y establecer parámetros
float coneAngle2 = CalculateConeAngle(emitter2);
float distance2 = CalculateDistance(emitter2);
bossApproachMusic.setParameterByName("Angle", coneAngle2);
bossApproachMusic.setParameterByName("Distance", distance2);
if (distance2 <= 50)
{
bossApproachMusic.setParameterByName("Initiated", 0);
bossApproachMusic.setParameterByName("Distance", distance2);
bossApproachMusic.setParameterByName("Angle", coneAngle2);
bossApproachMusic.start();
FMOD.RESULT baM = bossApproachMusic.start();
if (baM != FMOD.RESULT.OK)
{
Debug.Log(baM);
}
}
else
{
bossApproachMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
}
}
//FMOD.Studio.EVENT_CALLBACK dialogueCallback;
//crea instancias
public EventInstance CreateInstance(EventReference eventReference)
{
EventInstance eventInstance = RuntimeManager.CreateInstance(eventReference);
eventInstances.Add(eventInstance);
return eventInstance;
}
//ATRIBUTOS 3D AMBIENTES
public void Set3DAttributes(GameObject emitter, FMOD.Studio.EventInstance eventInstance)
{
// Obtener la posición y la orientación del objeto
Vector3 position = transform.position;
Vector3 forward = transform.forward;
Vector3 up = transform.up;
// Crear la estructura de atributos 3D de FMOD
FMOD.ATTRIBUTES_3D attributes = new FMOD.ATTRIBUTES_3D();
attributes.position = FMODUnity.RuntimeUtils.ToFMODVector(position);
attributes.forward = FMODUnity.RuntimeUtils.ToFMODVector(forward);
attributes.up = FMODUnity.RuntimeUtils.ToFMODVector(up);
// Opcional: también puedes configurar la velocidad si es relevante para el doppler
attributes.velocity = FMODUnity.RuntimeUtils.ToFMODVector(Vector3.zero);
// Establecer los atributos 3D en la instancia del evento DesertAmbience
bossApproachMusic.set3DAttributes(attributes);
musicBox.set3DAttributes(attributes);
bossMusic.set3DAttributes(attributes);
eventInstance.set3DAttributes(attributes);
}
//CALCULAR EL ÁNGULO CÓNICO BOSS
public float CalculateConeAngle(GameObject emitter)
{
// Buscar la cámara por nombre
Camera mainCamera = GameObject.Find("Camera").GetComponent<Camera>();
// Verificar si la cámara fue encontrada
if (mainCamera == null)
{
Debug.LogError("No se encontró la cámara con el nombre 'Camera' en la escena.");
return 0f; // Retornar un valor por defecto
}
Vector3 listenerPosition = mainCamera.transform.position;
// Dirección del emisor
Vector3 emitterForward = emitter.transform.forward;
// Dirección desde el emisor hacia el oyente (cámara principal)
Vector3 directionToListener = (listenerPosition - emitter.transform.position).normalized;
// Calcular el ángulo entre la dirección del emisor y la dirección hacia el oyente
float angle = Vector3.Angle(emitterForward, directionToListener);
return angle;
}
//CALUCULAR DISTANCIA
public float CalculateDistance(GameObject emitter)
{
// Buscar la cámara por nombre
Camera mainCamera = GameObject.Find("Camera").GetComponent<Camera>();
// Verificar si la cámara fue encontrada
if (mainCamera == null)
{
Debug.LogError("No se encontró la cámara con el nombre 'Camera' en la escena.");
return 0f; // Retornar un valor por defecto
}
// Calcular la distancia entre el emisor y el oyente
float distance = Vector3.Distance(emitter.transform.position, mainCamera.transform.position);
return distance;
}
//CALCULAR ELEVACIÓN
float CalculateElevation(GameObject emitter)
{
//GameObject emitter = GameObject.FindWithTag("Caja de Musica");
// Obtener la cámara principal como oyente
Camera mainCamera = GameObject.Find("Camera").GetComponent<Camera>();
// Posiciones del oyente y del emisor
Vector3 listenerPosition = mainCamera.transform.position;
Vector3 emitterPosition = emitter.transform.position;
// Vector dirección desde el oyente hacia el emisor
Vector3 direction = emitterPosition - listenerPosition;
// Obtener la distancia horizontal (en el plano XZ) y la diferencia de altura
float horizontalDistance = Mathf.Sqrt(direction.x * direction.x + direction.z * direction.z);
float verticalDistance = direction.y;
// Calcular el ángulo de elevación usando arctan2
float elevationAngle = Mathf.Atan2(verticalDistance, horizontalDistance) * Mathf.Rad2Deg;
return elevationAngle;
}
//INICIAR EVENT EMITTERS
public StudioEventEmitter InitalizeEventEmitter(EventReference eventReference, GameObject emitterGameObject)
{
StudioEventEmitter emitter = emitterGameObject.GetComponent<StudioEventEmitter>();
emitter.EventReference = eventReference;
eventEmitters.Add(emitter);
return emitter;
}
//ONESHOTS
public void PlayOneShot(EventReference sound, Vector3 worldPos)
{
RuntimeManager.PlayOneShot(sound, worldPos);
}
public enum EMusic
{
Menu,
Sand,
Forest,
BossApproach,
MusicBox
Boss
}
private EMusic currentMusic;
public void MenuMusic(bool shouldPlay)
{
switch (currentMusic)
{
case EMusic.Sand:
if (shouldPlay)
{
//stop area music
sandMusic.setPaused(true);
}
else
{
//play area music
sandMusic.setPaused(false);
}
break;
case EMusic.Forest:
if (shouldPlay)
{
//stop area Music
forestMusic.setPaused(true);
}
else
{
//play area music
forestMusic.setPaused(true);
}
break;
case EMusic.BossApproach:
if (shouldPlay)
{
//stop area Music
bossApproachMusic.setPaused(true);
}
else
{
//play area music
bossApproachMusic.setPaused(true);
}
break;
case EMusic.Boss:
if (shouldPlay)
{
//stop area Music
bossMusic.setPaused(true);
}
else
{
//play area music
bossMusic.setPaused(true);
}
break;
}
if (shouldPlay)
{
//play menu music
MenuMusica.start();
}
else
{
//stop menu music
MenuMusica.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
}
}
public void PlayMusic(EMusic music)
{
switch (currentMusic)
{
case EMusic.Sand:
//stop area music
sandMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
break;
case EMusic.Forest:
//stop area music
forestMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
break;
case EMusic.MusicBox:
//stop area music
forestMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
break;
case EMusic.BossApproach:
//stop area music
bossApproachMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
break;
case EMusic.Boss:
//stop area music
bossApproachMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
break;
}
currentMusic = music;
switch (music)
{
case EMusic.Sand:
//play area music
sandMusic.start();
DesertAmbience.start();
break;
case EMusic.Forest:
//play area music
forestMusic.start();
DesertAmbience.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
Debug.Log("Se detiene el ambiente del desierto");
BosqueAmbience.start();
Debug.Log("Comienza el ambiente del bosque");
break;
case EMusic.MusicBox:
//plays Music Box
forestMusic.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
musicBox.start();
case EMusic.BossApproach:
//play area music
bossApproachMusic.start();
FMOD.RESULT bAMresult = bossApproachMusic.start();
if (bAMresult != FMOD.RESULT.OK)
{
Debug.Log(bAMresult);
}
Debug.Log("Empieza la música del Boss");
BosqueAmbience.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
Debug.Log("Se detiene el ambiente del bosque");
break;
case EMusic.Boss:
//play area music
bossMusic.start();
break;
}
}
public void EnemyTalk(ETranslateID ID)
{
RuntimeManager.PlayOneShot("event:/EnemyTalk/" + ID.ToString());
//RuntimeManager.PlayOneShot("event:/Dialog/BossTalkGreet");
}
public void UpdateSoundSettings()
{
areaMusicEventInstance.setVolume(Overmind.Instance.Config.Sounds.Music);
MenuMusica.setVolume(Overmind.Instance.Config.Sounds.Music);
sandMusic.setVolume(Overmind.Instance.Config.Sounds.Music);
//value from 0->1
//Overmind.Instance.Config.Sounds.General
//Overmind.Instance.Config.Sounds.Ambients
//Overmind.Instance.Config.Sounds.Dialogues
//Overmind.Instance.Config.Sounds.SFX
//Overmind.Instance.Config.Sounds.Music
}
public void PlayDialog(ETranslateID ID)
{
//RuntimeManager.PlayOneShot("event:/Dialog/" + ID.ToString());
//RuntimeManager.PlayOneShot("event:/Dialog/dialog_0a");
var dialogueInstance = RuntimeManager.CreateInstance(FMODEvents.Instance.Dialog);
// Pin the key string in memory and pass a pointer through the user data
GCHandle stringHandle = GCHandle.Alloc(ID.ToString());
dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
dialogueInstance.setCallback(dialogueCallback);
dialogueInstance.start();
dialogueInstance.release();
}
private void Cleanup()
{
//Detiene las instancias creadas liberando memoria
foreach (EventInstance eventInstance in eventInstances)
{
eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
eventInstance.release();
}
foreach (StudioEventEmitter emitter in eventEmitters)
{
emitter.Stop();
}
}
private void OnDestroy()
{
Cleanup();
}
}
This
Thank you for all the support!