Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
6
Question by JJ · May 29, 2011 at 09:54 PM · audiosoundaudiosourceaudioclipisplaying

PlayOneShot returns false for isPlaying

It seems that if you play an audio clip with

audio.PlayOneShot(clipName);

and then if you trying to check if the audio.isPlaying it returns false even though the audio is obviously playing. When I use audio.Play, then isPlaying returns True as expected.

Am I missing anything? is there any way around this? as I do need to use PlayOneShot so that I can follow it with a delayed Play.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by aldonaletto · May 29, 2011 at 11:40 PM

In fact, PlayOneShot doesn't affect isPlaying. It starts the sound and gets ready to another one, even if the first is still playing. Play can start a new sound too, but the prior sound is stopped if still playing.
You can work around this by emulating a version of PlayOneShot based on Play, like this:

 var sound1:AudioClip;
 var sound2:AudioClip;
 var sound3:AudioClip;
  .
 function playSound(sound:AudioClip, vol:float){
   audio.clip = sound;
   audio.volume = vol;
   audio.Play();
 }
  .
 // play a sound this way:
   playSound(sound2,0.8);
  .

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image v01pe_ · Jun 21, 2016 at 06:57 PM 0
Share

That's not really a workaround for PlayOneShot, because you can't play multiple overlapping AudioClips through one AudioSource (which you can with the PlayOneShot and I guess that's the reason for it to exist).

avatar image Bunny83 v01pe_ · Jun 21, 2016 at 08:39 PM 0
Share

Well, if you want a "fire-and-forget" method, you can simply use the static method AudioSource.PlayClipAtPoint. It internally creates a temporary AudioSource which is immediately disposed once the clip has finished playing. You can't really interact with that temporary source. If you need that flexibility you can use something like this:

 public static AudioSource PlayClipAt(AudioClip clip, Vector3 pos, float volume)
 {
     AudioClip instance = new GameObject("temp audio").AddComponent<AudioSource>();
     instance.transform.position = pos;
     instance.clip = clip;
     instance.volume = volume;
     instance.Play();
     Destroy(instance.gameObject, clip.length);
     return instance;
 }

This method will do the same thing as "AudioSource.PlayClipAtPoint" but it returns the AudioSource instance that is created internally. The Destroy line will automatically destroy the instance when the clip has finished playing.

avatar image v01pe_ Bunny83 · Jul 02, 2016 at 12:37 PM 0
Share

Hmm interesting, didn't know about that. Still I think @brenden-frank's approach is the best to address the original question about PlayOneShot and isPlaying. In my case

  • I need overlapping sounds - thus the use of PlayOneShot

  • The sounds should respect the settings from the AudioSource that I use (volume, pitch, channel, 3D settings, etc.)

  • I want to know if any sound (played through PlayOneShot) is still playing

avatar image
7

Answer by Brenden-Frank · Nov 16, 2012 at 09:54 PM

I worked around this by writing my own isPlaying() method while wrapping a class around my audioclips. Hope it helps!

 private float startTime;
 
 private void PlayOneShot(AudioClip clip, float volume)
 {
     audioSource.PlayOneShot(clip, volume);
     startTime = Time.time;
 }
 
 public bool isPlaying()
 {
     if((Time.time - startTime) >= clip.length)
         return false;
     return true;
 }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image chetanmac · Aug 13, 2015 at 09:55 AM 0
Share

its working awesome answer!!!

avatar image toadnan · Sep 19, 2015 at 12:09 PM 0
Share

Great Answer

avatar image v01pe_ · Jun 21, 2016 at 01:20 PM 0
Share

Did the same like this:

 audioSource.PlayOneShot(clip);
 playTimeout = $$anonymous$$ath.$$anonymous$$ax(Time.time + clip.length, playTimeout);

and to check:

 public bool isPlaying { get { return Time.time <= playTimeout; } }
avatar image firepro20 · Apr 16, 2020 at 01:50 AM 0
Share

This fixed the issue I was having when checking for a single or double click, synced animations with audio perfectly!

avatar image
1

Answer by Jesse Anders · May 29, 2011 at 10:38 PM

I don't have an answer per se, but I can confirm the behavior you describe.

I'm tempted to say it's a bug, and might be worth reporting as such (it seems that the 'is playing' property should be useable even when the sound was played using PlayOneShot()). However, it may be the intended behavior (I'm not sure).

[Edit: Based on what aldonaletto says, I guess it's the intended behavior.]

[Edit 2: Just tried it out, and it looks like it is indeed the correct/intended behavior. I have to admit I didn't know PlayOneShot() functioned that way (the docs don't mention it), but I suppose it makes sense that it does.]

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jesse Anders · May 30, 2011 at 01:34 AM 0
Share

$$anonymous$$ike, looks like you're confusing PlayOneShot() with PlayClipAtPoint(). I can't say what exactly PlayOneShot() does behind the scenes, but if you invoke PlayOneShot() and watch the hierarchy pane, you'll see that no game object is created (at least none that's visible to the user). PlayClipAtPoint() behaves as you describe, but that's a different function. [Looks like $$anonymous$$ike deleted his comment...? Anyway, I'll leave this here just as additional clarification.]

avatar image
0

Answer by Raunchard · Nov 28, 2015 at 03:10 AM

Another approach I am using is checking the outputlevel of the audiosource. I read somewhere that getoutputdata is fairly cheap. + it works with playOneShot.

 _audiossource.GetOutputData(audioSamples, 0);
             float sum = 0;
 
             for (int i = 0; i < audioSamples.Length; i++)
             {
                 sum += audioSamples[i] * audioSamples[i]; // sum squared samples
             }
 
             var rmsValue = Mathf.Sqrt(sum / audioSamples.Length); // rms = square root of average
             var dbValue = 20 * Mathf.Log10(rmsValue / 0.1F); // calculate dB
 
             bool playing = false;
 
             if (dbValue != Mathf.Infinity && dbValue != Mathf.NegativeInfinity)
                 playing = true;
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image v01pe_ · Jul 02, 2016 at 12:39 PM 0
Share

Nice, didn't know about GetOutputData… might be interesting for other applications as well!

avatar image
0

Answer by w34edrtfg · Mar 12 at 01:48 PM

 using UnityEngine;
 
 public static class AudioSourceExtensions
 {
     public static bool IsPlayingOneShot(this AudioSource audioSource) {
         float[] audioSamples = new float[256];
 
         audioSource.GetOutputData(audioSamples, 0);
         float sum = 0;
 
         for (int i = 0; i < audioSamples.Length; i++) {
             sum += audioSamples[i] * audioSamples[i]; // sum squared samples
         }
 
         var rmsValue = Mathf.Sqrt(sum / audioSamples.Length); // rms = square root of average
         var dbValue = 20 * Mathf.Log10(rmsValue / 0.1F); // calculate dB
 
         return (dbValue != Mathf.Infinity && dbValue != Mathf.NegativeInfinity);
     }
 }

 

This is an extension method, which as it's name says, magically extends the original AudioSource class. To use it just:

  1. Create a file named AudioSourceExtensions and paste the class there.

  2. Call it like audiosource.IsPlayingOneShot()

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Play sound from an array, not random, and only once 3 Answers

How to get decibel's value of game's sound? 0 Answers

AudioSource won't play 2 Answers

Audio: -3db automatic attenuation on any audio playing? 0 Answers

Question about audio (AudioSource). My ingame sound doesn't sound like the original audio file? 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges