Reputation: 17
I've been reading about the different ways of programming sound into a c# XNA game. I've decided on using a sound instance for the volume controls, but while playing a .wav, I've realised that the sound will only play again after it's completed, whereas just using a Sound Effect .Play() (rather than an instance) will cause it to play multiple copies of themselves, should it be asked to. So my question is, in a scenario where holding down a button will cause a single sound effect to play multiple times at once (such as the repeating drone of a machine gun or the like), instead of waiting until the end of the sound file to loop; how would you use an instance? I assume that there is something I'm missing, or that an instance is not designed for this use. If so, what are the main differences between the basic options for a Sound Effect, and those of a Sound Effect Instance? Thanks in advance.
Upvotes: 1
Views: 3535
Reputation:
A SoundEffectInstance
is one single instance of a sound playing; by definition, it cannot be played more than one at a time. Of course, you can have multiple instances of the same SoundEffect
. In fact, this is basically what is happening when you call SoundEffect.Play()
: you are creating an instance and playing it.
With this in mind, there are several options on your plate. If you [presumably] want to prevent a billion sounds from fully playing when you hold down a button, you definitely should not be using SoundEffect.Play()
, as like you've discovered, many many instances will be created (this is potentially very bad for performance and overall management anyway). For lesser-frequent sounds that may be an okay method.
Having said that, in what way can the SoundEffectInstance
be used? Basically it can be restarted from the beginning. Note that you can STILL have multiple SoundEffectInstance
s of course, one (or more) per game component. In this way one of your guns can restart and not mess with a different gun's instance of the same sound. Or you can choose to only have one instance per sound effect for performance reasons.
I've had problems with trying to restart it the "simple" way:
instance.Stop();
instance.Play();
Historically this has not worked for me; if it does for you, disregard the following:
What I had to do was set up my own "restart" flag per instance. So I wrapped the SoundEffectInstance
class with my own like so:
//class that represents one sound effect instance PLUS restart flag
public class Sound
{
SoundEffectInstance instance;
bool restart;
public Sound(SoundEffectInstance i)
{
instance = i;
restart = false;
}
public bool PlayingOrRestarting()
{
return State == SoundState.Playing || restart;
}
public void Update()
{
if (restart)
{
instance.Play();
restart = false;
}
}
public void Play()
{
instance.Play();
}
public void Restart()
{
instance.Stop();
restart = true;
}
public void Stop()
{
instance.Stop();
restart = false;
}
public SoundState State
{
get { return instance.State; }
}
public float Volume
{
set { instance.Volume = value; }
get { return instance.Volume; }
}
public bool IsLooped
{
set { instance.IsLooped = value; }
get { return instance.IsLooped; }
}
}
With this method you have to call Update() every frame for every Sound
, so keep a collection of them somewhere or make them otherwise accessible.
Upvotes: 4