2D-Sound in Unity unabhängig abspielen
Häufig gibt ein Soundeffekt im Spiel ein akustisches Feedback über ein Ereignis. So könnte ein Ton erklingen, wenn die Spielfigur z.B. eine Münze einsammelt. Sounds werden der Spielszene in Unity normalerweise über eine Audio Source-Komponente hinzugefügt. Allerdings wird eine solche Geräuschquelle beim Einsammeln sofort zusammen mit dem Objekt aus der Szene entfernt, so dass der Clip keine Gelegenheit zum Abspielen hat. Dieser Umstand macht es erforderlich, ein separates Abspielobjekt auszulösen, welches sich nach dem vollständigen Abspielen selbst löscht und aufräumt. Dieser Artikel beschreibt Beispiele, um ein solches unabhängiges Abspielen zu realisieren.
Unity-Funktion PlayClipAtPoint
Unity selbst bietet seit einigen Versionen die Methode AudioSource.PlayClipAtPoint(SoundClip,Position)
an, die eine Audio-Datei ohne weitere Abhängigkeiten abspielt und aufräumt. Die Dokumentation enthält bereits ein leicht zu erweiterndes C#-Code-Beispiel:
using UnityEngine; public class Demo: MonoBehaviour { public AudioClip clip; //Assign in Inspector private void OnTriggerEnter(Collider collider) { ... AudioSource.PlayClipAtPoint(clip, transform.position); //Play clip at position of this object ... } }
Funktionsweise:
- Beim Einsammeln wird im Code lediglich der Befehl
AudioSource.PlayClipAtPoint(...)
aufgerufen. Die Funktion erstellt automatisch ein zusätzliches Spielobjekt mit Audio-Player und löscht es nach dem Abspielen. - Der Befehle benötigt eine Sound-Datei als ersten Parameter, für den sich z.B. ein public-Feld („clip“) eignet. Das Sound-Asset lässt sich dann im Inspector zuweisen.
- Der Befehle benötigt eine Position im Raum als zweiten Parameter, für den z.B. die Position des eingesammelten Objekts in Frage kommt.
Anmerkungen:
- Dieser Befehl wirkt dreidimensional, d.h. der Sound wird aufgrund seiner räumlichen Position zum Audio Listener, der normalerweise an der Kamera hängt, lauter oder leiser.
- Oft genügt es aber, ein Audio-Feedback räumlich unabhängig, abzuspielen. Hierfür lässt sich z.B. die Kamera-Position als räumliche Koordinate übergeben:
AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position);
Eigene Helfer-Funktion PlayClip2D
Die Helfer-Klasse Audio aus dem GDP-Toolkit stellt die Funktion PlayClip2D
bereit, die PlayClipAtPoint ähnelt, aber den Audiospieler für ortsunabhängigen 2D-Sound konfiguriert und über das Rückgabeobjekt Zugriff auf weitere Parameter gewährt.
- Lade die Klasse Audio.cs aus meinem GitHub-Repository herunter und kopiere sie in Dein Projekt.
- Füge
using GameDevProfi.Utils;
an den Anfang der C#-Datei ein, von der aus Du den Sound starten willst. - Rufe an der gewünschten Stelle
Audio.PlayClip2D(clip);
auf. Der Parameter clip muss auf ein Audio-Asset zeigen. Dieses könnte wiederum in deinem Script als Feld definiert werden, um es im Inspector zuweisen zu können.
Beispiel für die Nutzung:
using System.Collections; using System.Collections.Generic; using UnityEngine; using GameDevProfi.Utils; public class SoundDemo : MonoBehaviour { /// <summary> /// Clip to play, assign in Inspector. /// </summary> public AudioClip clip; void Start() { if (clip == null) { Debug.LogError("Assign an audio clip in Inspector."); enabled = false; } } void Update() { if (Input.GetKeyUp(KeyCode.Alpha3)) Audio.PlayClip2D(clip); } }
Wird die Taste 3 gedrückt, spielt der Sound ortsunabhängig ab.
AudioSource im Prefab auslagern
Um die Parameter des AudioPlayers visuell zu definieren, besteht eine weitere Möglichkeit darin, ein Prefab des AudioPlayers zu erstellen, das beim Einsammeln der Münze in der Szene instanziiert wird. Das automatische Löschen lässt sich ebenfalls durch die Audio-Helfer des GDP-Toolkit einbauen:
- Lade die Klasse Audio.cs aus meinem GitHub-Repository herunter und kopiere sie in Dein Projekt.
- Füge
using GameDevProfi.Utils;
an den Anfang der C#-Datei ein, von der aus Du den Sound starten willst. - Füge ein Feld vom Typ
GameObject
der Klasse hinzu. Erstelle ein leeres Objekt im Unity Editor, füge einen Audio-Player hinzu und speichere dieses Objekt als Prefab, in dem Du es auf das Projekt ziehst. Ziehe weise demaudioPlayerPrefab
-Feld Deines Scripts im Inspector dieses Prefab zu. - Rufe an der gewünschten Stelle
Instantiate(audioPlayerPrefab);
auf. - Damit das Objekt nach dem Abspielen gelöscht wird, füge sofort nach dem Instantiate eine Komponente vom Typ
Audio.AutoCleanup
hinzu.
Beispiel für die Nutzung:
using System.Collections; using System.Collections.Generic; using UnityEngine; using GameDevProfi.Utils; public class SoundDemo : MonoBehaviour { public GameObject audioPlayerPrefab; void Update() { if (Input.GetKeyUp(KeyCode.Alpha4)) { GameObject player = Instantiate(audioPlayerPrefab); player.AddComponent<Audio.AutoCleanup>(); } } }
Wird die Taste 4 gedrückt, spielt der Sound ortsunabhängig ab, in dem das Prefab dupliziert und ein AutoCleanup-Script hinzugefügt wird.
Zusammenfassung
Um einen Sound schnell und einfach abzuspielen, bietet Unity die Funktion AudioSource.PlayClipAtPoint
. Da diese keinen Zugriff auf Eigenschaften des Players gibt, lässt sich der Sound hier aber nicht positionsunabhängig abspielen. Die Funktion PlayClip2D
aus dem GDP-Toolkit zeigt eine ähnliche Implementierung, die den Player für 2D vorkonfiguriert und zudem Zugriff auf das Player-Objekt gewährt. Zudem besteht die Möglichkeit ein Prefab zu instantiieren, wodurch die präzise Konfiguration sogar im Unity-Editor möglich wird.