Das Abspielen von FMOD Events in Unity ist nicht besonders schwer, jedoch haben wir dazu verschiedene Methoden zur Verfügung, die je nach Anwendung mehr oder weniger Sinn machen könnten. In diesem Tutorial schauen wir uns an, wie wir FMOD Events in Unity abspielen können.
Lade dir das Unity & FMOD Projekt zu diesem Tutorial herunter.
Inhaltsverzeichnis
Wie spielt man FMOD Events in Unity ab?
FMOD Events in Unity können auf drei verschiedenen Arten abgespielt werden:
- Mithilfe des FMOD Studio Event Emitter Components.
- Durch die PlayOneShot Helper-Funktion im Code.
- Durch manuelle Deklaration und Start/Stop des Events im Code.
Alle Möglichkeiten haben praktische Vor- und Nachteile:
- Der Event Emitter erlaubt uns Events ohne Code abzuspielen. In Kombination mit dem Studio Parameter Trigger Component können wir zusätzlich Parameter verändern.
- Mit PlayOneShot können wir einen Sound mit einer Zeile Code abspielen. FMOD kümmert sich hier automatisch um das Abspielen und stoppt bzw. befreit die Soundinstanz aus dem Arbeitsspeicher. Ein Nachteil dieser Methode besteht darin, dass keine Parameterveränderungen möglich sind. Wenn der Sound durch einen In-Game Parameter verändert werden soll, dann eignet sich die Verwendung von PlayOneShot nicht.
- Das manuelle Abspielen von Sounds braucht dagegen mehr Code, ist aber deutlich flexibler zu manipulieren, da genau definiert werden kann, wann ein Sound oder Loop abgespielt und gestoppt werden soll, und an welcher Stelle Parameterveränderungen durchgeführt werden sollen.
Events mit dem Studio Event Emitter abspielen
Für ein einfaches Abspielen von Events erstellen wir ein neues GameObject und fügen den Studio Event Emitter-Component ein:
Wir finden hier verschiedene Einstellungsmöglichkeiten, mit denen wir das Abspielen von Events beeinflüssen können. Unter Play Event und Stop Event bestimmen wir, wann das Event abgespielt und gestoppt werden soll. Bei Event wählen wir das Event aus einer Liste von Events aus, die wir voher gebuilded haben. Aktiviere und deaktivere das vorher erstellete GameObject, um den Sound zu hören.
PlayOneShot
Mit der PlayOneShot Methode wird sofort eine Instanz eines Events an einer bestimmenten Position erzeugt (standardmäßig der Ursprung des GameObjects). Der Sound wird vollständig abgespielt und Parameter können wie bereits erwähnt nicht eingestellt werden. Der Code für PlayOneShot lautet:
FMODUnity.RuntimeManager.PlayOneShot("event:/BeispielEvent");
event:/BeispielEvent
ist ein Pfad und bezieht sich hier auf ein Event, das wir in FMOD Studio erstellt haben. Die Pfade folgen der FMOD Studio Event- und Ordnerstruktur. Alternativ kannst du ein Pfad per Rechtsklick auf ein Event in FMOD Studio kopieren.
Wir fügen diesen Code in der Update()-Funktion des Scripts ein. In der if-Anweisung prüfen wir, ob die Leertaste gedrückt wird. Wenn dies der Fall sein sollte, wird der Sound abgespielt:
if (Input.GetKeyDown(Keycode.Space))
{
FMODUnity.RuntimeManager.PlayOneShot("event:/BeispielEvent");
}
Der vollständige Code sieht so aus:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayOneShotBeispiel : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
FMODUnity.RuntimeManager.PlayOneShot("event:/BeispielEvent");
}
}
}
Wenn du dich jetzt im Play-Modus befindest und auf die Leertaste drückst, wird der Sound erklingen, den du im BeispielEvent eingefügt hast. An der oberen linken Ecke siehst du zusätzlich ein kleines Debug Fenster von FMOD, das dir die Laustärke in RMS und die Anzahl der abgespielten Voices anzeigt:
Exkurs: Was ist der Unterschied zwischen ein Event und eine Instanz?
Ein Event ist eine Soundeinheit, die du in FMOD Studio herstellst und über verschiedene Tracks, Parameter und Automationen verfügt. Aus dem Event wird im Spiel eine Kopie bzw. Instanz erstellt. Du startest im Spiel nicht das Event an sich, sondern die Instanz. Das ermöglicht mehrere Kopien eines Events zu haben, die gleichzeitig spielen.
FMOD Event manuell per Code abspielen und steuern
Vier Schritte sind notwendig, um ein Event in Unity manuell abzuspielen und zu steuern:
- Wir müssen eine Instanz deklarieren.
- Unity mitteilen, wann eine Instanz des FMOD-Events erstellt werden soll und wo sich das Event befindet.
- Die Instanz starten bzw. stoppen.
- Die Instanz aus dem Arbeitsspeicher befreien.
Gehen wir nun diese Punkte Schritt für Schritt durch.
Instanzdeklaration
Wir müssen alle Events, die in diesem Skript verwenden werden, als Instanz deklarieren, bevor wir weitermachen. In unserem Fall tragen wir diese Zeile im Code ein:
private FMOD.Studio.EventInstance instance;
Instanzherstellung
In der Start()-Funktion des Scripts erstellen wir nun unsere Instanz:
void Start()
{
instance = FMODUnity.RuntimeManager.CreateInstance(“event:/BeispielEvent”);
}
Instanz abspielen
Anschließend kann der Sound über die Zeile instance.start()
abgespielt werden. Ich habe auch hier die Zeile in der Update()-Methode unter einem if-Statement verpackt, sodass der Sound nur abgespielt wird, wenn wir die Leertaste drücken.
if (Input.GetKeyDown(KeyCode.Space))
{
instance.start();
}
Wenn du wieder das FMOD Debug Fenster oben links betrachtest, wirst du wahrscheinlich merken, dass bei mehrmaligen Drücken der Leertaste in Vergleich zu PlayOneShot nur eine Instanz des Events abgespielt wird. Der Sound wird jedes Mal abgebrochen. Das passiert, weil wir die Instanz in der Start()
-Methode erstellt haben. Diese Methode wird einmalig beim Spielstart ausgeführt. Wollen wir für jeden abgespielten Sound eine eigene Instanz haben, müssen wir Instanzherstellungs-Code auch im If-Statement Block packen.
Achtung: Bei dieser manuellen Methode werden Instanzen nicht automatisch aus dem Arbeitsspeicher befreit. Das kann zu Problemen führen. Wir fügen den Code instance.release();
nach dem Abspielen der Instanz ein, damit die Instanz auch befreit wird.
Der vollständige Code für den Script sieht so aus:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ManuellBeispiel : MonoBehaviour
{
private FMOD.Studio.EventInstance instance;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
instance = FMODUnity.RuntimeManager.CreateInstance("event:/BeispielEvent");
instance.start();
instance.release();
}
}
}
Wie spielt man FMOD Loops ab?
Loops können am sichersten durch die manuelle Methode abgespielt werden. Doch wie erstellen wir Loops und wie stoppen wir sie?
Gehen wir zurück zu FMOD Studio und betrachten im Projekt das LoopEvent. Eine Loop-Region kann durch klicken mit der rechten Maustaste auf den Eintrag “Add Loop Region” erstellt werden:
Anschließend können wir Loop-Region beliebig verschieben, ähnlich wie bei manchen DAWs. Bewege die Loop-Region so, dass sie die ganze Audiodatei umfasst, speichere und builde das Projekt.
Im Unity-Projekt starte die Loop-Szene und drücke auf die Leertaste. Du wirst merken, dass der Sound jetzt geloopt wird.
Wie stoppe ich FMOD Loops?
Mit der Codezeile
instance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
kann unsere EventInstance gestoppt werden. Wir fügen in Update()-Methode wieder eine If-Anweisung ein, die unseren Sound beim Tätigen der linken Kontrolltaste (STRG) stoppt:
if (Input.GetKeyDown(KeyCode.LeftControl))
{
instance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
instance.release();
}
STOP_MODE.ALLOWFADEOUT
respektiert die Release-Zeit in der ADSR-Modulation des Events (falls vorhanden). Wenn wir stattdessen ein abruptes Stoppen wünschen, dann verwenden wir stattdessen STOP_MODE.IMMEDIATE
.
Der vollständige Code für den Loop sieht so aus:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoopBeispiel : MonoBehaviour
{
private FMOD.Studio.EventInstance instance;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
instance = FMODUnity.RuntimeManager.CreateInstance("event:/LoopEvent");
instance.start();
}
if (Input.GetKeyDown(KeyCode.LeftControl))
{
instance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
instance.release();
}
}
}
Wir können jetzt abwechselnd mit der Leertaste den Loop starten und mit linken STRG-Taste unseren Sound stoppen. Probiere es aus!
3D Sounds abspielen
3D Events unterscheiden sich von 2D Events dadurch, dass ein 3D-Sound mit Verräumlichung (Spatializer Effekt) abgespielt. Es hat eine Lautstärkedämpfung basierend auf der Entfernung von der Instanz und dem Listener, sowie ein Panning basierend auf der Position der Instanz in die Richtung, in die der Listener gerichtet ist.
Ein Event braucht nicht unbedingt einen Verräumlichungseffekt, um ein 3D-Event zu sein. Es kann auch eingebaute Parameter (wie Entfernung, Richtung, etc.) verwenden, um Eigenschaften wie Lautstärke und Filter zu automatisieren, um auch den Eindruck der Verräumlichung zu vermitteln.
In FMOD Studio kann ein 2D Event ganz leicht zu einem 3D Event konvertiert werden, in dem man den Spatializer-Effekt auf dem Master-Track einfügt:
Ich werde nun die wichtigsten Spatializer Einstellungen kurz erklären:
- Min & Max Distance und Distance Attenuation Kurve: Die Min- und Max-Distanzeigenschaften und die Distance Attenuation-Kurve des Spatializers bestimmen zusammen, wie stark das Signal bei verschiedenen Entfernungen gedämpft wird. Das Signal wird nicht abgeschwächt, wenn sich der Zuhörer innerhalb der minimalen Entfernung des Spatializers befindet, ist -oo dB, wenn sich der Zuhörer außerhalb der maximalen Entfernung befindet, und fällt gemäß einer linearen quadratischen Kurve ab, wenn sich der Zuhörer von der minimalen Entfernung zur maximalen Entfernung bewegt. Je nach Kurve fällt das Signal unterschiedlich ab.
- Envelopment: Envelopment bestimmt das Ausmaß des Events in beliebiger Entfernung vom Listener. Der Auto-Modus stellt die minimale Ausdehnung auf 0 Grad ein und setzt die Sound Size (Klangröße) auf das Doppelte der Min-Distance-Eigenschaft des Spatializers.
- Der User-Modus ermöglicht uns, die Klanggröße und die minimale Ausdehnung des Spatializers manuell festzulegen, und der Aus-Modus deaktiviert die Klanggröße und die minimale Ausdehnung.
Im Code selbst müssen wir nur eine kleinere Änderung durchführen, nämlich FMOD noch mitteilen, wo sich die Instanz im 3D-Raum befindet. Dazu haben wir auch hier zwei verschiedene Möglichkeiten. Entweder machen wir das direkt in der Update()-Methode eines Skripts mit dieser Zeile Code:
instance.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(gameObject));
Oder wir hängen die Information einmalig nachdem wir die Instanz erstellt haben an das GameObject an:
FMODUnity.RuntimeManager.AttachInstanceToGameObject(instance, GetComponent<Transform>(), GetComponent<Rigidbody>());
Je nach dem, ob das GameObject ein RigidBody besitzt, können wir die Eine oder Andere Methode nutzen. Die zweite Methode braucht den RigidBody, um die Velocity des GameObjects zu ermitteln, und daraus z.B. ein Doppler-Effekt zu aktivieren. Der Beispiel-Code für ein 3D-Event sieht so aus:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Event3DBeispiel : MonoBehaviour
{
private FMOD.Studio.EventInstance instance;
void Start()
{
instance = FMODUnity.RuntimeManager.CreateInstance("event:/3DEvent");
// FMODUnity.RuntimeManager.AttachInstanceToGameObject(instance, GetComponent<Transform>(), GetComponent<Rigidbody>());
instance.start();
}
void Update()
{ instance.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(gameObject));
}
}
Bewege dich in der beigelegten 3DEvent-Szene mit den WASD-Tasten und der rechten Maustaste in den Raum und höre, wie der Sound sich verändert.