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 dem audioPlayerPrefab-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.

 

 

 

 

Dr. René Bühling

Hi, mein Name ist René und ich möchte Dir dabei helfen, deinen Traum vom eigenen Computerspiel Wirklichkeit werden zu lassen. Mein erstes kommerziell veröffentlichtes Spiel habe ich Mitte der 1990er Jahre als Hobby-Projekt mit einem Basic-Dialekt unter Windows entwickelt. Seither verfolge ich das Thema Spieleentwicklung in Hobby, Studium und Beruf. Ich habe über 20 Jahre Erfahrung in allen Phasen des Entwicklungsprozesses, die ich gerne mit dir teilen möchte.