Switch sound effects on one object depending of state (Idling, Thrusting)

Hi,

Instead of the boring silence when in idle mode I wanted to add a sound effect where the rocket is not on “afterburn” mode (a bit more decent tune). However, when it comes to coding I dont get it to work that

  1. Play idle sound
  2. If input Space; stop idle sound and immediately start thrust sound
  3. when releasing space stop playing thrust sound and play idle sound
  4. loop
    The only thing I could imagine is if I add another condition in the switch and play it there. Any efficient solutions?
[SerializeField] AudioClip mainEngine;
    [SerializeField] AudioClip GameOver;
    **[SerializeField] AudioClip IdleThrust;**
    [SerializeField] AudioClip Success;

then I state in update that it should play the idle sound:

 void Update() {

        { audioSource.PlayOneShot(IdleThrust); }
....
....


    public void Thrust()
    {
        float Booster = mainThrust * Time.deltaTime;
        audioSource.PlayOneShot(IdleThrust);

        if (Input.GetKey(KeyCode.Space))

           
            ApplyThrust(Booster); 

       
        else
        {
            audioSource.Stop();
        }
    } private void ApplyThrust(float Booster)


    { 
        
        rigidBody.AddRelativeForce(Vector3.up * Booster);

        if (audioSource.isPlaying == true) //no sound overlay
           audioSource.Stop();
else 
            { audioSource.PlayOneShot(mainEngine); }

Hi @JohnnyDerpo,

First of all, good job on challenging yourself. :slight_smile:

I tried to look into your code but, unfortunately, the formatting is quite difficult to read. If possible, please format your code properly.

Furthermore, what do you mean by “idle mode”? Have you already tried to move audioSource.PlayOneShot(IdleThrust); to the else block and remove the Stop() method?


See also:

Hi Nina,

Thank you for looking into it. I’ll try to tidy it up.

With idle mode I mean the condition when I am not pressing space which triggers the sound effect of the thrust. It is a slight change in the volume basically between 2 different soundfiles. One is for idle mode the other for the thrust mode.

I also tried to do the following:

  1. Initiate the idle sound in the first line of the void update(); condition

  2. Once I press space: First of all stop idle sound and initialise the “thrust” sound.

  3. When I release the space key (when gravity takes basically over) then it should go back to a slight idle sound.

  4. Both sounds cancelled in event of death (will implement success later on)

Similar to a fighter jet when he flies with after burner or without.

Anyway I will edit this post once I formatted my whole code to make it more user friendly.

Thank you very much for the help. Much appreciated

Best,

Johnny

It’s just a guess but maybe the problem is caused by PlayOneShot. How familiar are you with programming?

If you are familiar or if you want to challenge yourself, here is what you could try to use Play() instead of PlayOneShot and Pause. During runtime, you assign a sound clip to the AudioSource depending on the “state” of your rocket.

Since you are adding more complexity to your game, I’d also suggest to “outsource” the sound code from the ApplyThrust method and create a new method where you implement the logic for your sound and play the sound.

Thank you Nina,

I will try it in an isolated audio script and just call the keybinds script in there. Thanks for the hint.

Thank you

Best,

Johnny

Hi Nina,

I have now tried the following:

I have added two audio components to the same object and defined them in the code. Now at least I hear the two sounds but the stop command isnt working (or is constantly looping the stop when holding space key down). It gets a werid output. Do you have an idea how to structure the code that:

a) On game initialisation it should play the idle sound
b) When pressing Space key the idle sound should stop and instead play the Thrust sound
c) When releasing the space key it should return to idle sound.

public class SoundTest : MonoBehaviour
{

    Rigidbody rigidBody;
    AudioSource mainThrust;
    AudioSource idleSound;

    // Start is called before the first frame update
    void Start()
    {
        rigidBody = GetComponent<Rigidbody>();
        AudioSource[] allMyAudioSources = GetComponents<AudioSource>();
        mainThrust = allMyAudioSources[0];
        idleSound = allMyAudioSources[1];
    }

    // Update is called once per frame
    void Update()
    {
        idleSound.Play();

        if (Input.GetKey(KeyCode.Space))




        { 
               idleSound.Stop();
               mainThrust.Play();
           
        }
        
          
        
    }
}

Screenshot from Inspector View:

Okay for those who want to achieve something similar, here’s the solution and there will be a smooth transition:

The better code to use is
if (Input.GetKeyDown(KeyCode.Space))
and
if (Input.GetKeyUp(KeyCode.Space))

the code before was always interrupting the sound because the GetKey == false check will always interrupt the loop.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SoundTest : MonoBehaviour
{

    AudioSource mainThrust;
    AudioSource idleSound;

    enum State { Idling, Thrusting }


    // Start is called before the first frame update
    void Start()
    {
        AudioSource[] allMyAudioSources = GetComponents<AudioSource>();
        idleSound = allMyAudioSources[0];
        mainThrust = allMyAudioSources[1];
    }

    // Update is called once per frame
    void Update()



    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            idleSound.Stop();
            mainThrust.Play();
        }

        else if (Input.GetKeyUp(KeyCode.Space))
        {
            mainThrust.Stop();
            idleSound.Play();
        }

    }
}

Good job on solving the problem, and thanks for sharing your solution! :slight_smile:

I think the problem might have been that the Play method got called each frame, which causes the AudioSource to start the sound clip at the start. With your new solution, you only play/stop the AudioSource in the frame when the key was pressed or released, not multiple times per second anymore.

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

Privacy & Terms