Summary of the project:
There’s an event in a project I’m working on where rocks (KActors in this case) fall from the top of a cliff and land in a small river, so this next foray into UDK sound is about water collisions. I thought it would be fairly simple to set up the UTWaterVolume with a Physical Material that had an impact sound assigned to it, but after hours of trying out different combinations of collision properties for the KActors and water volume, I decided to do something custom in Kismet instead. This would also allow me to trigger different sounds for large, medium and small impacts, as well as trigger exit splash sounds and lateral sloshing sounds.
My basic plan was to make sounds (6 variations of each) for large, medium and small occurences of 3 splash types: water entry, water exit and in-water lateral movements. Then I would add these sounds to my level somewhere off the edge of the map so they’re out the way, and use trigger volumes in Kismet to move the appropriate actor to the splash location when needed.
Setting up the water and trigger volumes
For setting up the water, I recommend watching this tutorial by Raven. I also added some particle effects for the water splash. Once you’ve got that set up you need to add 2 trigger volumes, one for triggering entry and exit splashes (hereafter referred to as TriggerVolume_1) and the other for triggering the lateral movement splashes (TriggerVolume_2). TriggerVolume_1 should cover the entire water volume, overlapping as closely as possible. TriggerVolume_2 should be as wide and long as the water volume but only 16 units deep, and should be placed just below the surface of the water. The images below show the green trigger volumes in the viewport – I’ve separated them out a bit from the water and reverb volumes to make it easier to see what’s going on.
Adding the actors
I added each of my sound waves as AmbientSoundToggleable actors and placed them just off the edge of the map. I used the barrel static mesh that comes with UDK for my KActors and placed them next to the water so I could toss them into the water with the physics gun. (To add assets to your map, select the asset in the editor, right click in the viewport, select Add Actor, the listed menu items should include some suggested actors for your asset.)
There’s a setting in the KActor properties that needs to be changed in order to register a touch event in Kismet: select the KActor in the viewport, hit F4 and find the No Encroach Check property in the Collisions section – uncheck it.
Kismet
Here’s an overview of the Kismet sequences I made for this project:
To get the Trigger Volumes to work, you need to set the Class Proximity type to whatever it is you want to make the splash (could be ‘Actor’ if you want to include everything) and untick Player Only. This is done in the Trigger Volume properties in Kismet:
Here’s a rundown of what’s happening in each sequence:
Entry Splashes
1. When TriggerVolume_1 is touched by the KActor, assign the KActor to an object variable, get the location of the KActor and store it to a vector variable.
2. Create a new vector variable by taking the co-ordinates of the first vector and adding 30 units to the Z co-ordinate – this is so when we move the sound actor to the splash location, the sound always plays above water, ie. isn’t affected by the reverb volume’s low pass filter.
3. Get the KActor’s speed and compare it against 3 ranges of values, for small, medium and high impacts (the screenshot below only shows the sequence for medium impacts, the range of values for small impacts is greater than 80 and less than or equal to 400, and the range for large impacts is greater than 700.)
4. Next up is a random integer node for values 0 to 5, for our 6 medium splash sounds, followed by a repetition avoidance routine which stops the same sound playing twice. After that there’s a couple of comparison nodes to determine the number chosen by the randon integer node.
5. The next step in the sequence moves the selected sound actor to our pre-defined location and plays it once.
Exit splashes
The exit splashes work in the same way but are triggered by the Untouched output on the Touch event node.
Lateral movements
1. When TriggerVolume_2 is touched by the KActor, capture its velocity and compare it to a very small threshold value to determine whether or not it’s actually moving.
2. If the actor is moving, wait a fraction of a second (0.03s) and capture the velocity again.
3. Get the location of the KActor for use later on.
4. Subtract the second velocity reading from the first velocity reading to get a rudimentary idea of the acceleration (if I ever go back to this project I’ll use a proper equation that includes distance and time!).
5. Create a new vector variable by taking the co-ordinates of the first vector and adding 100 units to the Z co-ordinate – this is so when we move the sound actor to the sloah location, the sound always plays above water, ie. isn’t affected by the reverb volume’s low pass filter.
6. Compare the acceleration value against 3 ranges of values as before to determine which set of slosh sounds to move onto, small, medium or large. (again, the screenshot above only reveals the sequence for medium sloshes).
7. Run through the random number generator as before, and move the selected sound actor to the predefined location.
8. There’s an extra step in this sequence, which uses a simple bool routine to stop a currently playing sound from being triggered again. This prevents a sound being cut off prematurely when the same sound has previously been triggered and has just been stopped.
9. If the actor ‘Untouches’ the trigger volume and is below it, play a ‘glug glug’ sinking sound.
The Reverb volume
The reverb volume provides a low pass filter on sounds originating outside the reverb volume while the player is listening from inside it – this is applied to all splash and slosh sounds, since they are deliberately positioned just outside the reverb volume. It also adds a LPF to sounds originating inside the reverb volume while the player is listening from outside – in this case it gets applied to the glug sound played when an object is sinking. There’s also some underwater reverb. Here are the ReverbVolume settings:
There’s a video of this in action in the third reel of my game audio showreel.