Here AudioSource it says that " You can’t stop Audio when PlayOneShot
is used".
My question is: how are we stopping the ThrustAudio when we die or win the level or when we stop pressing space while we are alive if supposedly you can’t stop the audio till is finished?
Hi Arnau,
What do the instructors in the videos use for the thrust sound?
They use PlayOneShot, here is the code:
private void RespondToThrustInput()
{
if (Input.GetKey(KeyCode.Space))
{
ApplyThrust();
}
else
{
audioSource.Stop();
mainEngineParticles.Stop();
}
}
private void ApplyThrust()
{
float thrustThisFrame = mainThrust * Time.deltaTime;
rigidBody.AddRelativeForce(Vector3.up * thrustThisFrame);
if (!audioSource.isPlaying)
{
audioSource.PlayOneShot(mainEngine);
}
if (!mainEngineParticles.isPlaying)
{
mainEngineParticles.Play();
}
}
}
PlayOneShot stops automatically when the clip is played. It does not loop. Since the clip is short, we do not have to stop it when the player dies or when we win the level.
When a new scene gets loaded, all non-persistent objects in the scene get destroyed. A destroyed AudioSource object cannot play anything.
Does that make sense?
That is what should happen, but the thrust audio is 6.184 seconds long. I press space for less than one second, then I stop pressing space, the audio, which has been playing for 0.5 seconds/6.184 seconds, stops playing. The same happens to Ben.
When the rocket dies, even when you start pressing space one second before exploding, the thrust audio stops.
Here is the code when it dies or succeeds. As you can see, Ben has placed an audioSource.Stop() in StartSuccessSequence() and StartDeathSequence() to stop the thrust audio. If it stopped automatically after 6.184 seconds, there would be no stop in this two functions. If I delete the audioSource.Stop() from these two functions then the thrust audio continues to sound till is finished, therefore, the stop does work.
void OnCollisionEnter(Collision collision)
{
if (isTransitioning || collisionsDisabled){ return; /* stop execution*/ }
switch (collision.gameObject.tag)
{
case "Friendly":
//do nothing
break;
case "Finish":
StartSuccessSequence();
break;
default:
StartDeathSequence();
break;
}
}
private void StartSuccessSequence()
{
isTransitioning = true;
audioSource.Stop();
audioSource.PlayOneShot(success);
successParticles.Play();
Invoke("LoadNextScene", levelLoadDelay); /*1 second delay*/
}
private void StartDeathSequence()
{
isTransitioning = true;
audioSource.Stop();
audioSource.PlayOneShot(death);
deathParticles.Play();
Invoke("LoadStartScene", levelLoadDelay); /*1 second delay*/
}
That’s interesting. Unfortunately, most of Unity is not open-source, so we have to rely on the information in the API and the manual. Sometimes, the information is outdated.
Have you already tried to increase the levelLoadDelay
to verify that the Stop method does stop the AudioSource? When it comes to seconds, Unity is not that precise because a lot is going on behind the scenes.
I have only two ideas on why this is happening:
1- Now Unity lets you stop a PlayOneShot(mainEngine). In this case, when you stop pressing space it stops the audio due to the audioSource.Stop() in RespondToThrustInput().
2- What we are stoping is the audioSource that is linked to the thrust audio and not the thrust audio itself. See the code. I don’t know if what I am saying has any sense. It looks like we are assigning the thrust audio to the audioSource component of the rocket.
public class Rocket : MonoBehaviour
{
Rigidbody rigidBody;
AudioSource audioSource;
[SerializeField] float rcsThrust = 100f;
[SerializeField] float mainThrust = 100f;
[SerializeField] float levelLoadDelay = default;
[SerializeField] AudioClip mainEngine = default;
[SerializeField] AudioClip success = default;
[SerializeField] AudioClip death = default;
[SerializeField] ParticleSystem mainEngineParticles = default;
[SerializeField] ParticleSystem successParticles = default;
[SerializeField] ParticleSystem deathParticles = default;
bool isTransitioning = false;
bool collisionsDisabled =false;
private void Start()
{
rigidBody = GetComponent<Rigidbody>();
audioSource = GetComponent<AudioSource>();
}
private void RespondToThrustInput()
{
if (Input.GetKey(KeyCode.Space))
{
ApplyThrust();
}
else
{
StopApplyingThrust();
}
}
private void StopApplyingThrust()
{
audioSource.Stop();
mainEngineParticles.Stop();
}
private void ApplyThrust()
{
float thrustThisFrame = mainThrust * Time.deltaTime;
rigidBody.AddRelativeForce(Vector3.up * thrustThisFrame);
if (!audioSource.isPlaying)
{
audioSource.PlayOneShot(mainEngine);
}
if (!mainEngineParticles.isPlaying)
{
mainEngineParticles.Play();
}
}
Hi @Arnau_Castillo,
I’m sorry that I haven’t replied earlier. For some reason, I missed your reply.
Do you still need help with this or did you manage to fix the issue? It might well be that Unity changed the behaviour of PlayOneShot in newer versions of Unity.
This topic was automatically closed after 5 days. New replies are no longer allowed.