ubiqvisuals

Login Form




3D Action Adventure Kit Sound FX Documentation

Part 1: The Basics

Note: This documentation is specific to TGEA, not the newest T3D build. Most of the workflow is still relevant but specific lines of code called out or editor shortcut keys may no longer be relevant.

Usually thought of last but one of the most important elements…
You guessed it. Sound. Arguably one of the most under-rated yet most important elements of any game or interactive software. You may go for months without hearing any sound in your game and as soon as you start adding sounds the environment and the characters will really start to come alive! We have tried to make it as easy as possible to understand the sound workflow and modify the existing sound effects to work with whatever type of game you choose to make. In part 2 of this documentation we will go into more of the coding specifics for those who want to understand and learn more.

The basic Maco character has 22 different animations for which we have added SoundFX:

  • Run
  • Walk
  • Stop
  • Running Jump
  • Standing Jump
  • Running Land
  • Standing Land
  • Hug a wall and idle, walk left, or right
  • Climb up, left, right, down, idle
  • Grab a ledge & move left, right, or idle
  • Pull yourself up from a ledge grab
  • Injury, Death

Some of these animations are also context sensitive and therefore depending on what surface Maco is standing on, we need to play a different sound. We separated the sound effect into three categories: player is on the terrain, player is on a dif interior object, or player is climbing on a dif.

How are sounds played?
The basic flow of how a sound is played in the engine goes something like this:

sound_flow

Animation = Sound
As you can see, the sound that play is dependent on an embedded sound trigger that the animator places into the player animations. This method really makes sense because the animation will dictate what sort of sound plays, so putting these two elements together works well.

How can I create Animation Triggers to play my sounds?
First off, this is something fairly straight forward to do and we will explain how. If one were to use Maya, they would follow the procedures listed below. If you wish to use 3D Studio Max there is some documentation that can be found here: http://www.garagegames.com/docs/tge/general/ch08s05.php
This lesson is presuming know how to use Maya and have the Maya2DTS exporter installed with a a character animated and are ready to start adding triggers for your sounds. If you are not that far in your process please refer back to our Character Animation tutorial for help on getting a character built and imported into the game.

Adding Footsteps
Let’s start with the most basic sound effect: the foot step. The Torque Game Engine already has built in code to handle footsteps and all you need to do as an artist is hook these up.

To do so is simple. First, in your outliner, select the particular sequence you wish to add the sound (as seen in the picture below). If you are using separate .dsq animation files (which is highly recommended) then there should only be 1 sequence node in your particular Maya file.

Next, open up your Maya2DTS exporter window and select from the menu DTS>Sequences>Add Trigger (as seen in the picture below). This adds two trigger Attributes to your sequence: TriggerFrame0 and TriggerState0. You may need to scroll down in the Channel Box to see them.

add_trigger

Scrub to the frame in your animation where you would like a sound to play for the left foot step. In the TriggerFrame0 box you will need to input this frame number that you have currently scrubbed to where you want the sound to play. For TriggerState0 you will want to input the number 1. Why 1? Well in code, a trigger with the state of 1 means “play the left footstep sound.” Often people think that the state is either 1 or 0 meaning on or off. Don’t think of the state as an “on/off” switch (or as in binary 1 is on, and 0 is off). Think of it more as a flag telling the engine that “hey this frame has occurred.” You can have up to 32 different states for your triggers.

Note: The number 0 directly after the words Frame and State only means that it is the first trigger created in the sequence (remember programmers start counting from 0, not 1).

Okay so that was easy right? Now let’s do the exact same thing to create another set of triggers for the right footstep sound. This time the triggers will be labeled Trigger Frame1 and Trigger State1. Scrub to where the right foot plants and input the corresponding frame into the TriggerFrame1 attribute, and for the TriggerState1 you want to put 2. A TriggerState of 2 represents a right foot plant sound in the engine by default.

So now we’re almost done! All we have to do is export this thing. Ah wait, but there’s a trick…

Tricking the Exporter?
Make sure you read the following two tricks you need to do to have your triggers export or your triggers may not export correctly:

  1. For some reason the exporter will only export your triggers if Ignore Ground if OFF. So make sure you turn it off.
  2. You also need to trick the exporter by animating the bounding box. If you do not animate the bounding box the triggers will not export. If you do not want your player bounding box to animate (which in most cases you don’t) then just put a key frame at the start, middle, and end of your animation. The start and end key frames should be identical, and for the middle key frame just move the bounding box by .001 units. By doing this you are tricking the exporter that the bounding box is animating and it will export your triggers.

ignore_ground

All Done!
You should now be able to open your animation in Show Tools to check if the triggers have exported correctly. If you open your model and load in your .dsq on the left hand side there’s a button labeled “Sequence Info.” If you click on it you should see your animation in that list. If you highlight your animation in the bottom right of the window under Sequence Triggers, you should see your triggers listed in there. You will notice that the No. and State don’t reflect what you saw in Maya. Don’t worry, that’s normal, all that matters is that if you see a trigger in there you’re good to go! If you’re having trouble loading your animations into ShowTools please refer to the ShowTools documentation.

What if I want to adjust sounds that aren’t for the footstep sounds?
If you want to keep things simple by just replacing the current sound effects with your newly created ones, then for your animations you just need to follow our rule of thumb for what TriggerState’s trigger what sorts of sounds:

TriggerState 1 = any time his left foot makes a sound
TriggerState 2 = any time his right foot makes a sound
TriggerState 3 = any time he makes any other sound (usually it’s his clothes or backpack rustling)

Does setting a Trigger State to a certain number mean the same sound will play every time?
No. Each trigger state is not bound to a specific sound. Because each animation calls for different sounds (walking and running should have different sounds playing, even though they both use TriggerState’s 1 and 2), and depending on what surface the player is on, it also plays a different sound. The trigger state only tells us in the code “hey look this trigger just happened!” In code, we watch for the same triggers, and depending on which animation is playing and what surface the player is on, we play a sound effect.

Modifying Maco’s Sound Effects
The easiest and recommend way to modify Maco’s default sound effects and replace them with your own are to simply overwrite the existing audio files located in:

\game\scriptsAndAssets\data\sound\player

The file names are very explicit about what sound they are for. Many of the sounds have multiple variations. These are similar sounds which are played randomly each time that TriggerState is occurred. For example, for the run animation we have 3 different footstep sounds. That means that each time the code encounters a TriggerState 1 or 2 pick from one of these three sounds and play it.

If you want to see which animations have which triggers feel free to open up the source animation files so that you may see how we placed the triggers.

How do I create my own Sound Effects?
While this tutorial is not about how to be an audio artist, the easiest (and most fun!) way to get sounds is to record your own (yay Foley!). Record on as high quality as possible as you always want your source audio to be as good as it can get. If you don’t feel like doing Foley there are plenty of free audio sources online if you just search for “free sound effects.”

Next open your sound file in a sound editor such as Sound Forge or Audacity (free) and play with them until your heart is content. We found that the following specs give decent results when exporting your audio file:

  • 192 kbps
  • 44,100 Hz
  • Mono

If the sounds are going to be for the player they need to be mono sounds. This is because the player sounds have an “is3D” audio profile, which means that the game engine will decide where in 3D space the sounds should be played.
The game engine will accept both .wav and .ogg files. Wav files maintain great quality but are much larger when compared to .ogg files which compress fairly well. It’s up to you which format you wish to choose.

Why are my sounds making popping/crackling sounds?
Most of the time this is due to either two reasons:

  • Your sound drivers need to be updated or you need to switch to a different audio device. Sometimes when you have 3D sounds your audio driver will have trouble playing them and may pop/crackle.
  • Make sure you have a quick fade in and fade out at the end of your files so that the sound wave doesn’t clip. This will minimize any cracks and pops your sounds may produce while in game.

That wraps things up!
If you’re only interested in replacing Maco’s sound effects and don’t wish to learn the more technical side of things then you can stop reading now. However if you would like to understand more about the code and how to add in your own new sound effects and triggers please continue reading! Even if you’re apprehensions about coding we strongly recommend taking a stab at it. It’s not too hard and we try to make it as easy as possible to follow.

Part 2: Advanced

Assumptions
This section assumes that you have some-what of an understanding of basic coding practices and also that you have the Torque Source Code. If you do not have the source code you will not be able to add any new sounds to you game, you will only be able to replace the current ones with new ones.

Adding New Sounds
Okay so you understand the basics of the sound workflow and it’s time to spread your wings and really take control of your own game’s audio. Probably the first thing you’ll want to learn is how to make a new sound for your player and have that sound play in the game. The following steps are necessary to add new sounds into the game:

  • Declare and define your sound in the player.cs script file using a SFXProfile
  • Create a new variable in the Player datablock and assign your SFXProfile
  • Add the sound into the Sounds Enum Block
  • Add the sound into the player.cpp initPersistFields()
  • Play the sound when the player performs a particular animation

1. a Adding your Sound into the Player Datablock
Open up your player.cs script file (game\scriptsAndAssets\server\scripts). Near the top you will notice a whole bunch of datablocks. Each of these SFXProfile datablocks adds a new sound to the game.

1. datablock SFXProfile(playerWalk01Terrain)
2. {
3.   filename = "~/data/sound/player/player_walk01_terrain.ogg";
4.   description = AudioClosest3d;
5.   preload = true;
6. };

Line 1: declares a SFXProfile Datablock. Inside the brackets is what you will be naming the sound file in code.
Line 3: indicates the location of your sound file.
Line 4: indicates what type of Audio Profile your sound will have. I will get into this in just a second.
Line 5: indicates if this sound will be preloaded. For all your player sounds you will want to have preloaded set to true.

1.b The Audio Profile
The audio profile of a sound controls some of the higher level attributes of the sound. If you would like to modify your audio profiles you can open the audioProfiles.cs file located in the same directory as the player.cs.

1. datablock SFXDescription(AudioClosest3d)
2. {
3.   volume = 1.0;
4.   isLooping= false;
5.   is3D = true;
6.   ReferenceDistance= 30.0;
7.   MaxDistance= 100.0;
8.   channel = $SimAudioType;
9. };

Line 1: declares a SFXDescription Datablock with the name of it inside the brackets (notice how the name is the same name as what you used for “description” in the SFX Profile in the previous step.

Line 3: a volume of 1.0 means play the sound at 100% full volume. 0.1 would mean play the sound at 10% of its volume.

Line 4: if you want the sound to loop, set this to true. For most player sounds you will want to have a non-looping sound.

Line 5: if your sound is a sound that will be placed dynamically in 3D space keep this true.

Line 6: ReferenceDistance means that you need to be within 30 torque units of the sound in order to hear it at full volume. This is only relevant if your sound is a 3D sound

Line 7: MaxDistance means if you are further away than 100 units you will not hear the sound. This is only relevant if your sound is a 3D sound

Line 8: there are three channels your audio can play in. $DefaultAudioType (channel 0), $GuiAudioType (channel 1) is used for any GUI sounds, and $SimAudioType is for any in-game mission stuff. You can create more channels if you wish but for now let’s stick with using these three.

2. Adding your Sound into the PlayerData Datablock
This step may seem redundant but we need to declare the sounds again in the PlayerData datablock which can be found if you scroll down in the player.cs file.

In this PlayerData datablock you will need to create a new variable and then assign your SFXProfile to it.

walk01TerrainSound = playerWalk01Terrain;

Adding this variable into the PlayerData datablock allows the C++ code to see the sound effect. The new variable name you created (in this case walk01TerrainSound) will be the name that the C++ code looks for.

3. Add the sound into the Sounds Enum block
First you will need to open up your player.h C++ file. This can be found in:

\engine\source\T3D\player.h

Scroll down to around the 116th line and you will notice an enum Sounds {}. Inside this Enum we are storing all of the sound effects that the player can perform. Insert a unique name related to your sound effect by typing it inside the curly brackets and ending with a comma. It doesn’t matter where inside the block you put the sound just as long as it’s in there somewhere! Make sure you remember the name you give it because we will need it for the next step.

enum Sounds {
  climbIdle,
  climbUp01,
  walk01Terrain, //I just inserted this new sound
  ImpactWaterHard,
  ExitWater,
  MaxSounds
};
SFXProfile* sound[MaxSounds]; 

4. Add the sound into the player.cpp initPersistFields() method
Now you’ll need to open up your player.cpp C++ file. This file can be found in the same place as the player.h file

Note: If you are unfamiliar with C++, most of the time each C++ file comes as a pair: a .h file (a header file) and a .cpp file (a C plus plus file). The header file can be thought of as a summary of what will be included in the .cpp file. All of the functions and variables that will be used in the .cpp file are declared in the .h file.

The player.cpp file is a large file that controls everything to do with your character; sound included. Scroll down to somewhere around the 620th line and you’ll see a whole bunch of lines that look like this:

addField("walk01TerrainSound", TypeSFXProfilePtr, Offset(sound[walk01Terrain], PlayerData));

5. Playing the sound when the player does something – last step!
Lets scroll down a bit further in the player.cpp file until we find the method updateActionThread() which will be around line 3400. This is where all our hard work starts to pay off.

Basically what you will see in here are a handful of if statements. What we are checking for is to see what animation the player is currently performing. If they are playing a specific animation, then we want to play the sound specific to that animation. It looks something like this:

01. //running on terrain
02. if(mActionAnimation.action == PlayerData::RunForwardAnim)
03. {
04.   //throw in some random variation of the sound
05.   S32 randInt = mRandI(1,3);
06.   switch(randInt)
07.   {
08.     case 1: playSound(PlayerData::run01Terrain); break;
09.     case 2: playSound(PlayerData::run02Terrain); break;
10.     case 3: playSound(PlayerData::run03Terrain); break;
11.   }
12. }

Line 2: This if statement checks to see if the animation the player is currently performing is the one that we are looking for. In this case we are looking to see if the current animation being played is the Running Animation.

Line 8: If the current animation being played is the animation we are looking for then play the appropriate sound!
You will notice we use a temporary random integer (randInt) and throw that into a switch statement to add some variation. What is basically happening is that the mRandI() method is generating a random number from 1-3. Whatever number it generates, we are telling the switch statement to find that case number and play the sound associated with it.

Note: The UpdateActionThread() method is called every tick so the engine is constantly checking to see if the animation trigger has happened or not.

Finished!

We hope you’ve found this bit of documentation useful in learning how to create and control sound in the Torque Game Engine using our 3D Action Adventure Kit as an example to learn from! If you have any questions or comments please feel free to post on the Ubiq Visuals support forums.