PlayOneShot audio repeating bug (Unity 3)

I’m seeing an intermittent bug on an iPhone build where short sounds (less than 1 sec) initiated by audio.PlayOneShot somehow get caught in an endless repeat loop that continues until you exit the scene. Anyone else seeing this?

Yes, we got it too. Unfortunately they were unable to reproduce it.

The “loop” boolean becomes ivnerted accidentally when you run for some reason.

You could try to place the sound efx in a prefab, instantiate it with an isPlaying query every 1/10th of a second and when it is not playing it destroys itself, or alternately get the length in seconds of the clip and set the object to destroy itself after that time is completed.

HTH
BTH

same problem here iphone 3.0 PlayOneShot

Bluster T Hogwash your idea is not good. I got far too many sounds to test them every 1/10th of a sceond.

I see you neglected part two. The destroying the prefab as soon as its time played is up. You don’t have to test for it. Just place a var in the Inspector or on Instantiation get the clip length and set the Destroy in a yield statement to that amount of seconds after. Your choice is either deal with the overlap or create a workaround…or await a fix. Drove me crazy for weeks and I handled it this way.

BTH

Thanks for the workaround. I had the same problem.

Here’s the code of the MonoBehavior in question:

using UnityEngine;
using System.Collections;

[RequireComponent (typeof(AudioSource))]

public class AudioSelfDestruct : MonoBehaviour {

	float length = 0.0f;

	IEnumerator selfDestruct()
	{
		yield return new WaitForSeconds ( length );
		Destroy ( gameObject );		
	}

	void Start () {
		length = audio.clip.length;
		StartCoroutine( selfDestruct() );
	}
}

What if you want to use the AudioSource again?

  • First load the audio source to a GameObject. Keep it in the scene.
  • To play the sound, clone the first one with GameObject.Instantiate( mySoundObject )
  • Add the AudioSelfDestruct component to the object.
  • Call PlayOneShot on this one.
  • Repeat step 2 to 4 to play it again and again.

yep all fine solutions but they don’t work if u have to use the sounds often (Pinball Game / Multiball) i get serious lags when i always instantiate new sounds and have many timers running together.

Especially on the last iPod generation. PhysX ist already almost killing it :wink:

I just ran into this problem as well. Does not occur in the editor, but does occur on the device build. Is it restricted to just short clips? If that’s the case, does adding silence to the end of the clip seem to help?

I thought that too and tried adding silence, but it didn’t solve the problem. In the end I have gone with something similar to what jrobichaud suggested. Not ideal, but solves the problem until PlayOneShot is fixed.

Unfortunately I cannot always replicate the problem (seems to happen at random) so I haven’t submitted a formal bug report.

@ezone, yep, I’m in the same boat. I’ll have to try to track this problem down. Does it occur for you too on an AudioSource with many sounds played through it? I have a generic AudioSource that is a child of the camera, and I send many PlayOneShot messages through it. Just curious if this might be a common thread to look into.

Does is happen if you do it manually IE:
audio.clip = someClip;
audio.loop=false;
audio.Play();

I’m getting this bug as well…

I seem to be able to reproduce it pretty consistently, but it takes ages…

I have been experiencing it in Unity 3 and Unity 3.1.

It’s almost like the Editor gets tired of specific sounds once they have been used a lot, or when a lot of sounds get used on top of each other… Typically if I have been playing my game for a while the default spell-cast sound starts looping… so then I switch to a different spell and restart the game and that spell is fine… but only for a while, because once I have used that sound enough then it will start looping whenever it is played… Gradually this happens to many of the sounds in my game… Even if I stop the game playing and start it again it remembers these… And what is really strange is that for any sound that it has been looping it will start looping again after only one play, which means that, after testing my game for a long time, whenever I play it rapidly becomes a cacophony.

Right now I am playing all my sound effects through only one AudioSource… it doesn’t say anywhere that this is a bad idea… but could it be? It isn’t the AudioSource itself that is causing the looping problem, because the AudioSource is instantiated and deleted each play. Sometimes multiple PlayOneShots of the same AudioClip happen simultaneously on this one AudioSource. The clips that break and start repeating seem to be the clips that are played most often, not necessarily the ones that get played multiple times at the same time.

If I deactivate the AudioSource it will stop repeating, however like I have said, the next time any of the previously repeating clips plays that clip will start repeating again.

I am playing all my Audio Clips from references stored in prefabs in the project. So typically it will look like this :

SoundClass.PlaySound(soundPrefab.audioClip, volume);

And in SoundClass :

public static void PlaySound(AudioClip clip, float v) {
audioSource.PlayOneShot(clip, v);
}

I think it clears itself if I restart Unity… trouble is that I have heard this happen on the device. (iPad)

Instantiating and deleting sound objects isn’t a reasonable option for me performance-wise… I am going to try one or two things to see if a different sound setup will help.

Yup, that is how I am doing it too. What I’ve ended up doing is using this code for all PlayOneShots to a script attached to the camera:

function PlayOneShotDestroy (clip : AudioClip, volume : float) {
    var go = new GameObject ("One shot audio");
    go.transform.position = transform.position;
    go.transform.parent = transform; // makes sure that the sound stays with the camera
    var source : AudioSource = go.AddComponent (AudioSource);
    source.clip = clip;
    source.volume = volume;
    source.Play ();
    Destroy (go, clip.length);
    return;
}

I haven’t noticed any performance impact when compared to using PlayOneShot…

OK, now we’re talking. I might be able to come up with a test case in my copious free time… maybe it’s the collision of multiple PlayOneShot calls on a single audioSource. So your workaround works fine?

So far so good - haven’t had the repeating sound problem again.

I’ve caved in and implemented the Ezone destroy workaround. This is what I’m doing now (the only differences from Ezone’s suggestion is that I am using C#, not creating a new gameObject and using 2D sounds so that position doesn’t matter) :

   public static void PlaySound(AudioClip clip, float v) {
        if (clip == null) return;
        AudioSource  tempSource = (gameObject.AddComponent(typeof(AudioSource)) as AudioSource);
        tempSource.PlayOneShot(clip, v);
        Destroy(tempSource, clip.length);        
    }

Seems to be working so far…

I’m really upset about this, this cannot be good for performance. Where are the Unity moderators?

Hi,
We’re looking into this. FMOD have some issues with looping compressed sounds with duration < ~1s.

Hopefully this will be fixed in the next release.

Søren

Thanks!

Though I’m not using any compressed or looping sounds and the problem still occurs (it’s looping sounds that should not ever loop).

Looking forward to the next release!