In questo tutorial, vi mostrerò come riprodurre un file audio in Unity e, cosa più importante, come ho risolto un problema relativo alla sovrapposizione della riproduzione audio da una Audio Source.
Trascrizione del video
Salve a tutti! In questo tutorial, vi mostrerò come riprodurre un file audio in Unity e, cosa più importante, come ho risolto un problema relativo alla sovrapposizione della riproduzione audio da una Audio Source. Prima di procedere, vi prego di notare che la soluzione presentata nel video è quella che ho adottato personalmente per questo problema, ma è probabile che esistano altre soluzioni (e forse migliori); quindi, non considerate le informazioni fornite qui come l'approccio definitivo... anzi, se avete soluzioni alternative, non esitate a condividerle nei commenti!
Il video è stato realizzato utilizzando la versione 2022 di Unity. In particolare, voglio riprodurre un file audio di passi (proveniente dal primo gioco di Prince of Persia di Jordan Mechner, che è stata la mia prima esperienza di gioco su PC) quando il personaggio si muove all'interno della scena. Questo può sembrare un compito semplice, ma come scopriremo, cela una piccola sfida.
Per riprodurre l'audio dei passi, il primo passo è quello di attaccare un oggetto Audio Source al personaggio. All'interno di questo oggetto, definiremo il file audio specifico da riprodurre e configureremo altre proprietà di riproduzione.
Un Audio Source è un componente che deve essere aggiunto a un oggetto all'interno della scena. Questo potrebbe essere il personaggio, una porta, una palla o anche un oggetto invisibile—utile per riprodurre un file audio quando il personaggio entra in una stanza specifica o si avvicina a un particolare oggetto.
Perché l'audio sia udibile dalla Main Camera, la Camera deve avere un componente Audio Listener attivo.

Nei nuovi progetti Unity, la Main Camera solitamente è dotata di un componente Audio Listener attivo per impostazione predefinita, dato che si presume che gli utenti vorranno sentire i file audio. Se l'Audio Listener predefinito manca, può essere aggiunto tramite l'Inspector dell'oggetto Main Camera.

Nel mio scenario, il file audio deve essere collegato al personaggio. All'interno del mio progetto, c'è un oggetto Player che serve come genitore della Main Camera. Lo script di movimento è associato all'oggetto Player, mentre la camera è dotata di uno script per abilitare la visuale libera. Di conseguenza, attaccherò un componente Audio Source all'oggetto Player.
Una volta aperta la scheda del componente appena creato, vedremo immediatamente il campo AudioClip, che è inizialmente impostato su 'None'. Inoltre, c'è una casella di controllo denominata "Play on Awake" che è selezionata per impostazione predefinita. Questa opzione riproduce il file audio quando il gioco inizia, il che può essere vantaggioso in determinati scenari. Tuttavia, non è necessario per il nostro caso d'uso attuale, quindi la deselezionerò.

Importare un clip audio nel progetto è piuttosto semplice: trascinare semplicemente il file audio da una finestra del Browser di file nella scheda Progetto o selezionarlo dal disco tramite la finestra Assets - Import New Asset.

Unity è compatibile con vari formati audio, come mp3, e visualizzerà un'icona di nota musicale accanto all'elemento corrispondente all'interno del Progetto.
Come potete vedere, il mio progetto contiene già diversi file audio destinati alla riproduzione in momenti diversi. Tra questi file, quello a cui siamo specificamente interessati è "PoP---walk".
Per procedere, seleziono prima il Player nella Gerarchia. Successivamente, clicco e tengo premuto il pulsante sul file PoP---walk nella scheda Progetto. Infine, trascino questo elemento nella casella AudioClip del componente AudioSource associato al Player.

Come precedentemente menzionato, il suono dovrebbe essere riprodotto quando il personaggio si muove. Per ottenere questo risultato, aprirò lo script responsabile del movimento del personaggio e inserirò il codice richiesto.
Innanzitutto, creo una variabile di tipo AudioSource e la inizializzo all'interno della funzione Start associandola al componente AudioSource del Player. Per fare ciò, scrivo il seguente codice:
private AudioSource playerAudioSource;
e, all'interno della funzione Start:
playerAudioSource = GetComponent();
Devo anche creare una variabile AudioClip da associare al file audio che deve essere riprodotto. Chiamerò questa variabile myAudioClip e utilizzerò l'attributo SerializeField perché voglio che sia visibile nell'Inspector. Dopo aver salvato il file di script, il passaggio successivo sarà trascinare l'asset "PoP---Walk" nel campo myAudioClip dello script all'interno dell'Inspector.
Immediatamente dopo la definizione di playerAudioSource, scrivo la seguente riga di codice:
[SerializeField] private AudioClip myAudioClip;

Dopo aver salvato lo script, torno all'Editor di Unity e procedo a trascinare l'asset "PoP---Walk" nel campo myAudioClip dello script, come descritto in precedenza.

Al momento, l'audio non viene riprodotto.
All'interno della funzione Update dello script, ci sono delle istruzioni per rilevare i tasti premuti dall'utente, che controllano il movimento del personaggio.
Nello specifico, quando l'utente muove il personaggio, il valore di Input.GetAxis per Horizontal e Vertical (che ho rinominato x e y per comodità) può essere sia -1 che 1, a seconda della direzione. In questo caso, potrei scrivere il seguente codice:
if ((Mathf.Abs(x) == 1) || (Mathf.Abs(z) == 1)) playerAudioSource.PlayOneShot(myAudioClip);

e provare ad eseguire il gioco; tuttavia, farlo sarebbe un errore significativo perché Unity riprodurrebbe il file audio DURANTE OGNI FRAME DEL GIOCO!
La situazione non migliora se spostiamo semplicemente la funzione PlayOneShot all'interno di una Coroutine (che sto chiamando "Walk") e aggiungiamo un comando di ritardo di un secondo (yield return new WaitForSeconds(1)). Il problema rimane che Update chiamerebbe la Coroutine ad ogni frame, riportandoci allo stesso errore.
La Coroutine, quindi, non è necessaria. Invece, dobbiamo implementare un semplice controllo sull'AudioSource: riprodurre l'audio solo se l'AudioSource NON lo sta già riproducendo.
Questo può essere fatto all'interno della funzione Update scrivendo il seguente codice all'interno del blocco if che controlla i valori di x e y:
if (!(playerAudioSource.isPlaying)) playerAudioSource.PlayOneShot(myAudioClip);

Ora possiamo salvare lo script, avviare il gioco e osservare (o, meglio ancora, ascoltare) il risultato.
Prima di concludere questo video, un'ultima osservazione: il campo AudioClip del componente AudioSource può, ovviamente, essere modificato tramite script. Ciò significa che è possibile utilizzare questo AudioSource per riprodurre un file audio standard dei passi, ma anche sostituire la clip audio durante il gioco con un altro se, ad esempio, il personaggio sta camminando su della ghiaia, sulla riva di un corso d'acqua, o su altre superfici, che possono essere identificate utilizzando i Collider. Inoltre, se il personaggio può volare, si potrà disabilitare l'AudioSource in modo che nessun suono venga riprodotto.
Bene, per questo tutorial è tutto; spero vi sia stato utile! A presto!