Using a positional audio and environmental effects

Audio is an incredibly powerful mood setter and should not be overlooked in a game. In this recipe, we'll go through how to make the most of your sound assets using runtime effects and settings. If you're simply looking for omnipresent sounds or the basics on how to play them, check out Chapter 1, SDK Game Development Hub.

This recipe will do well in an FPS, where you have a number of footstep sounds that are played when the player moves around. However, the principle is true for any short sound that is played often enough to sound repetitive.

We'll approach this recipe in two steps:

  1. First, we will learn how to vary a basic, repetitive sound. We can achieve this by varying the sound's pitch and using LowPassFilter.
  2. In the second step, we'll use reverb to vary it further, depending on the scene.

How to do it...

First of all, we need some basics set up.

  1. We create a new application extending SimpleApplication, and add an AudioNode field called audioNode.
  2. In addition to this, we need to keep track of passed time with a float field called time and another float field called pauseTime, which we set to 0.7f.
  3. In the simpleInitApp method, we create a new audioNode instance:
    new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg");
  4. We override the simpleUpdate method and begin by checking whether time is more than pauseTime.
  5. If it is, we should set a new float called pitch. This should have a value of 1f +- 10%, which can be achieved with the following code:
    FastMath.nextRandomFloat() * 0.2f + 0.9f.
  6. Then, we call audioNode.setPitch(pitch) to set it.
  7. Since this particular sound file plays four footsteps in sequence, we tell the node to not start from the beginning and only play the last of the footsteps by skipping forward in time, using the following code:
    audioNode.setTimeOffset(2.0f);
    audioNode.playInstance();
  8. Before exiting the if statement, we set time to 0.
  9. Finally, we shouldn't forget to increase time by tpf.
  10. Try running the application now. We should hear the same sound over and over again but with a slight variation.
  11. We can use LowPassFilter to further vary the sound. We instantiate it by supplying a float for the general volume, and another for the high frequency volume. To get the most variation, we can supply two random values between 0f and 1f:
    LowPassFilter filter = new LowPassFilter(FastMath.nextRandomFloat(), FastMath.nextRandomFloat());
  12. Then, we call audioNode.setDryFilter(filter) before audioNode.playInstance().
  13. When we play it again, we should hear a slightly more varied sound that from time to time gets more muffled.

Reverb is another parameter we can use for our sounds. But unlike the previous examples, this should not be randomized each time we play it (or randomized at all!). We can add reverb using the following steps:

  1. Create a new instance of Environment in the simpleInitApp method using one of the premade static ones in the Environment class and telling the application's audioRenderer to use it:
    Environment env = Environment.Cavern;
    audioRenderer.setEnvironment(env);
  2. Running the application again with this environment should give each footstep a huge echo.

How it works...

In the first part of the recipe, we varied a single sound by changing its pitch slightly every time it was played. This will still sound repetitive and it is recommended to have several premade variants of a sound and use it in combination with this technique to get more out of them.

At the time of writing this, filters are not developed past LowPassFilter and have a limited use. It can still be used to cut the dryness of the sound and make it more muffled, as if heard through a wall, for example.

Having a sound file with a sequence of footsteps, like the one in the test-data library is fine for some types of games. They work best when you know how far a character will move each time, such as in an RTS or turn-based game. In an FPS, however, where we don't know how fast or far a player decides to move, it's better to have footstep sounds split up and played individually based on movement speed.

Using an Environment class is a great way to add immersion to sounds without having to bake the effect into the sound file. Controlling the effect unless it's level-wide can be a bit trickier. For example, you may want more reverb outside than in a furnished room. One way could be to use the trigger system from earlier in the chapter and big bounding volumes triggering a change in environment as the player enters their area.

In this example, we used the setDryFilter method of the audioNode. This will not modify any reverb coming from the environment. To do that, we have to use setReverbFilter.

There's more

The recipe has covered playing audio originating from the player. It is almost as easy doing this for other entities in the scene. Since AudioNode extends Node, it has a position in the scene graph. Attaching an AudioNode instance to the scene graph will play the sound using its worldTranslation field, just like how a model will be shown at that location.

Apart from setting localTranslation, we also need to make sure that the positional Boolean in AudioNode is true (which it is by default). We're also only allowed to use mono channel sounds when using positional audio.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.2.157