AudioSource AudiClip

Hello everyone
Please help
Sorry for the big text

I moved away from Rick’s video for a bit and ran into a problem

My ship is constantly flying forward
The W key raises the ship up
S - down
A - left
D - right

I want to

  1. The “engine sound” was constant, but when you press the WASD keys, the “engine sound” turned off
  2. When pressing the WASD keys, the displacement sound turned on

I completed the first task using AudioSource:

AudioSource droneMoveAudio;

void ForwardSpeed()
{
if (Input.GetKey(KeyCode.W))

    {

        if (droneMoveAudio.isPlaying)

        {

            droneMoveAudio.Stop();

        }

    }

else if (Input.GetKey(KeyCode.S))

    {

        if (droneMoveAudio.isPlaying)

        {

            droneMoveAudio.Stop();

        }

    }

else if (Input.GetKey(KeyCode.A))

    {

        if (droneMoveAudio.isPlaying)

        {

            droneMoveAudio.Stop();

        }

    }

else if (Input.GetKey(KeyCode.D))

    {

        if (droneMoveAudio.isPlaying)

        {

            droneMoveAudio.Stop();

        }

    }

else if(!droneMoveAudio.isPlaying)

    {

        droneMoveAudio.Play();

    }

}

Now I need to create a method that will turn on a different sound when WASD is pressed, and turn that sound off when the keys are turned off

I first created a AudioClip to put it in a method similar to the first one. But in the AudioClip there are no Stop and Play functions

I do not know what to do
Maybe it is possible to assign properties AudioSourse to AudioClip so that there is access to the functions Play and Stop?

Hi snamina,

It’s great to see that you are challenging yourself. You also have a solid concept, so I’m sure you’ll be able to make your idea work. :slight_smile:

I agree with you. A dedicated method for enabling/disabling sound would be great because, at the moment, there is a lot of duplicated code, which makes changing details bothersome because you would have to do that “everywhere”.

Do you know method overloading? Here is an example:

void PrintName (string yourParameterName)
{
    Debug.Log(yourParameterName);
}

// When calling the method:
PrintName("Rick");

With this, you could create a method which is supposed to start/stop the audio source and do not have to copy and paste the same lines of code all over the place. Instead, you could write one method for it.

If you want to make the same audio source play another sound, the PlayOneShot method might be interesting for you. Look it up in the API. Alternatively, override the clip value of the AudioSource object during runtime. There is an example in the API.

Clips cannot be stopped. Only the AudioSource can. Like a radio.

I hope this helped a bit. I don’t want to write too much because I feel that you might want to solve this problem yourself. If you need more advice, feel free to ask. :slight_smile:


See also:

Thanks Nina for your answer
Yes, I use this method call at update.

About my question
in the method I described above, I tried using PlayOneShot:

if (Input.GetKey(KeyCode.W))
{
if (droneMoveAudio.isPlaying)
{
droneMoveAudio.Stop();
droneMoveAudio.PlayOneShot(droneMoveSideSound);
}
}

It turned out that the ship flies with “engine sound”, when you press the W key, the “engine sound” turns off and the “displacement sound” on (the sounds overlap each other), but when you release the W key, the “displacement sound” continues to play, but the “engine sound” should return.

In general, it is not clear to me how I should describe PlayOneShot so that the sounds do not overlap. And so that when the keys are released, the “engine sound” returns and the “displacement sound” stops

What exactly would you like to hear? Is the “engine sound” supposed to play simultaneously with the “displacement” sound or do you just want to play one sound at a time?

Your code looks correct so far. You stop the AudioSource, then you call PlayOneShot. However, the if-block gets executed only if the W key is pressed down. And while the key is pressed, this code gets executed each frame. Maybe you should play the audio source only in the frame when one of the keys was pressed down. Replace the GeyKey method with GetKeyDown to see what happens.

Try that first before you read what I wrote below. Maybe the rest of my answer is irrelevant for you.


Since you want a specific sound clip to play if the WASD keys are pressed, you could write an if-condition like this:

if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.A))
{
   // your code
}

|| means “or”, && means “and”.

Since programmers are “lazy”, we could check the user input with a method. If you want to add more keys, you won’t have to copy and paste things.

// The keys that make your player move
KeyCode[] movementKeys = [
    KeyCode.A,
    KeyCode.W,
    KeyCode.S,
    KeyCode.D
];

bool IsMovementKeyPressed()
{
    // Check all movement keys in a loop,
    // return 'true' if one of the keys is pressed
    // else 'false'
    foreach (key in movementKeys)
    {
        if (Input.GetKey[key]) { return true; }
    }

    return false;
}

Now you could simply do this in Update:

if (IsMovementKeyPressed())
{
   /* your code for playing the "engine sound" */
}
else
{
   // whatever is supposed to happen if no movement key is pressed
}

Now you just have to think about your idea and implement the sound logic, not the movement logic. You do not want to stop the current sound if the audioSource is playing the correct sound. If you cannot figure out what sound is being played, you could use two AudioSources; one AudioSource for each sound.

Thanks Nina

I think in my case the solution is to create another similar method and use the second AudioSourse in it

I’m going to see how to do it.

Nina I did it.

Not quite like I wrote above.

Since I did not find information on how to work with two audio sources on one object

I added a similar method in sphere that belonged to the player empty and added the second audio sourse there and script

Great job! I’m wondering if it is possible to get rid of the click sound. Apart from that detail, your solution works well. :slight_smile:

Maybe pausing and playing the sound instead of stopping it would solve the problem. Instead of Play() and Stop(), you would call Pause() and Unpause(). :confused:

Working with 2 AudioSources is not difficult. All you have to do is to reference both.

// Assign the AudioSource components in the Inspector
[SerializeField] AudioSource droneMoveAudio;
[SerializeField] AudioSource engineAS;

// in your method:
droneMoveAudio.Pause();
engineAS.UnPause();

Would you mind sharing your solution?

Sure

Here is a fragment of the script from the “player” prefab

void ForwardSpeedSound()
    {

        if (Input.GetKey(KeyCode.W))
        {
            if (droneMoveAudio.isPlaying)
            {
                droneMoveAudio.Stop();
            }
        }

        else if (Input.GetKey(KeyCode.S))
        {
            if (droneMoveAudio.isPlaying)
            {
                droneMoveAudio.Stop();
            }
        }

        else if (Input.GetKey(KeyCode.A))
        {
            if (droneMoveAudio.isPlaying)
            {
                droneMoveAudio.Stop();
            }
        }

        else if (Input.GetKey(KeyCode.D))
        {
            if (droneMoveAudio.isPlaying)
            {
                droneMoveAudio.Stop();
            }
        }

        else if(!droneMoveAudio.isPlaying)
        {
            droneMoveAudio.Play();
        }

    }

Here is a fragment of the script from the sphere, which is inside the “player” prefab

void Wasd()
   {
        if (Input.GetKey(KeyCode.W))
        {
            if (!droneMoveSideSound.isPlaying)
            {
                droneMoveSideSound.Play();
            }
        }
        else if (Input.GetKey(KeyCode.S))
        {
            if (!droneMoveSideSound.isPlaying)
            {
                droneMoveSideSound.Play();
            }
        }
        else if (Input.GetKey(KeyCode.A))
        {
            if (!droneMoveSideSound.isPlaying)
            {
                droneMoveSideSound.Play();
            }
        }
        else if (Input.GetKey(KeyCode.D))
        {
            if (!droneMoveSideSound.isPlaying)
            {
                droneMoveSideSound.Play();
            }
        }
        else
        {
            droneMoveSideSound.Stop();
        }
    }

Nina I have another question

// Assign the AudioSource components in the Inspector
[SerializeField] AudioSource droneMoveAudio;
[SerializeField] AudioSource engineAS;

// in your method:
droneMoveAudio.Pause();
engineAS.UnPause();

And how do we understand which audio source component in the inspector we are referring to?

You manually drag and drop your audio source 1 to droneMoveAudio, and audio source 2 to engineAS. As if you had two radios: one for music, one for the news. Which one you use for what is completely up to you.

You named your audio source variables droneMoveSideSound and droneMoveAudio. If you assigned two different audio source objects to them, you did what I tried to explain in my previous answer. :slight_smile:

Thanks for your help Nina

You’re welcome. :slight_smile:


See also:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms