Sounds in Unity 3D

This article will be attached a small but useful script, and it is shown how to use it.
The reason for writing this article was the fact that there is a need to set up and test the sound effects without starting stage of the project. And also in the tracing of the main events playback.

The script works the same as in the PlayMode and in EditMode, and allows you to:
1. Play sound with the necessary delay and track to start playing.
2. Track the end of the sound, including every moment of completion of the looped playback.
3. Track unplanned ending sound.
4. Use the event to monitor and change the setting during playback.

To play sound using static methods:

public static SoundTrack PlaySound(AudioClip clip, float volume = 1, float pitch = 1, float loopTime = 0, float delayTime = 0);

public static SoundTrack PlaySound(GameObject target, AudioClip clip, float volume = 1, float pitch = 1, float loopTime = 0, float delayTime = 0);

These methods return an instance of the class SoundTrack, which subsequently can be attached to the required events. The first method creates on stage GameObject, the second adds the specified components GameObject SoundTrack and AudioSource.

Parameters volume and pitch do not need, probably, in the view.

loopTime - can be used to set the time in seconds that will last cycle of reproduction. A value of 0 sound lost only once, at a value of float.PositiveInfinity sound will be played indefinitely.
delayTime - is the delay before playback of sound in seconds.

     At the end of loopTime, the first method is designed to remove the sound GameObject, the second method removes only started to sound components.

Sample code for sound reproduction in the game.

public AudioClip testSound;

void Start () {
    SoundTrack.PlaySound (testSound);

And playback in the  sound editor.

[MenuItem("MyMenu/TestSound #F1")]
static void TestSound(){
    AudioClip[] clips=Resources.FindObjectsOfTypeAll<AudioClip>();
        Debug.LogError("No clips in the resources!");

Now you can try to deal with the events. I think, for clarity, it is better to take an example to the editor, as in play mode it works similarly.

This example starts the keyboard shortcut SHIFT + F1, and shows how to use the event.

using UnityEngine;
using UnityEditor;
using System.Collections;

public class SoundTrackTest : Editor {

    [MenuItem("MyMenu/TestSound #F1")]
    static void TestSound(){
        Debug.Log("clips " + clips.Length);
            Debug.LogError("No clips in the resources!");
        rePlayCount = 0;
        StartNextSound (0);
    static AudioClip[] clips;
    static int rePlayCount=0;
    static void StartNextSound(float timePosition){
        SoundTrack track=SoundTrack.PlaySound(clips[Random.Range(0,clips.Length-1)]);

        // Event start sound
        track.start_action += soundStartEvent;

        // Event is triggered every frame
        track.processing += soundProcessEvent;

        // This event is only suitable for looped playback
        // It is activated every time the sound is completed
        track.complete_action += soundCompleteEvent;

        // Event is triggered when you remove the sound
        track.destroy_action += soundDestroyEvent;

            // Rewinds the playhead to a specific point in seconds
            track.setTimePosition (timePosition);
    static void soundStartEvent(SoundTrack track){
        Debug.Log("Sound Start event!");
    static void soundProcessEvent(SoundTrack track){
        track.volume = track.playing_time % 1f;
    static void soundCompleteEvent(SoundTrack track, float offset){
        Debug.Log("Sound Complete event! "+offset);
    static void soundDestroyEvent(SoundTrack track, bool atEndOfSound, float offset){
        Debug.Log("Sound Destroy event! "+offset);

        // Checks whether the destruction is initiated due to the end of play
        // atEndOfSound Is set to false if the playback was interrupted for other reasons
        // for example when you remove the sound from the scene by hand
            // This approach demonstrates how to seamlessly connect multiple serial sounds
            // offset - this is an inevitable delay call events 
            // You can use it to compensate for the next sound track.setTimePosition

            // this is done to the sounds in the editor is not reproduced indefinitely
            // as if the sound is very short, it will be a very unpleasant taste
                StartNextSound (offset);


To example to work, the script must be put in a folder Editor, as well as have the resources of the project at least one audio file. If you need a test in running the project, you can simply transfer function TestSound code in the function Start, and if needed, to make all non-static properties and methods.

void Start(){
    Debug.Log("clips " + clips.Length);
        Debug.LogError("No clips in the resources!");
    rePlayCount = 0;
    StartNextSound (0);

This event is triggered directly at the beginning of the sound.

track.start_action += soundStartEvent; // Event start sound

Ie if delayTime> 0, it does not trigger the creation of sound, and the playback start.

This event may be useful in some cases.

track.processing += soundProcessEvent; // Event is triggered every frame

For example, you can set the effects of music and different events, and one variable to adjust the volume of the music in the game, and the other all the effects. And then add effects and music one more event, which already regulate the speed of play, if the game has the effect of Slow Motion.
In this example, the sound must for every second to change the volume.

track.complete_action += soundCompleteEvent; // Event is triggered every time the sound is completed

This event can be useful in situations where loopTime exceeds the length of the sound file, which means that the sound will be played in cycles. In this case, the event will be triggered at the moment when the sound starts again. In other cases, the challenge of this event is not guaranteed.

track.destroy_action += soundDestroyEvent; // event is triggered when you remove the sound

This event is triggered in 2 cases. The first case is when the sound reproduction is completed, after loopTime disposable or playback. The second case, it is in no way connected with the logic of the script the removal of the sound from the stage (eg manually remove the object from the scene hierarchy). To distinguish one from the other case, you can use the parameter atEndOfSound, if it is false, then this is just the second time.

In the second case we will not have access to GameObject'u and sound components.

If for example you must consistently play a few tunes and create a sense of continuous playback, you can try to do it as shown in the example in the function soundDestroyEvent.

In addition, the script has parameters that may be needed:

     time_position - the position of an audio file, from 0 to the length of the file;
     life_time - time to start playback of sound;
     playing_time - time spent on sound, does not account for the pause;
     loop_time - the time that the sound will be played;
     delay_time - time delay before playback;
     startTime - the beginning of the sound;
     created_time - the moment of creating sound (startTime-delay_time).

All the time is calculated with respect to Time.realtimeSinceStartup.

Here you can download the script and the above example.

If the example does not work a keyboard shortcut, you can find the item in the menu TestSound.

If Unity does not find a sound resource, you have to simply highlight (see the settings of the audio file).

All data posted on the site represents accessible information that can be browsed and downloaded for free from the web.


User replies

No replies yet