Adding Sound Effects - mariusz-tang/KTaNE-Module-Template GitHub Wiki
Using the game's built-in audio system
To add audio to your module, first import the sounds you'd like to play into your project.
Then, simply call one of KMAudio
's PlaySound
methods. The name
parameter should exactly match the name of the audio file, without the file extension. Additionally, you need to tag the sounds as part of the mod.bundle
.
When passing in the name of the audio clip, I recommend storing a reference to the AudioClip
object itself, and using its name
parameter, as this makes changing sounds later much less error-prone.
private KMAudio _audio;
[SerializeField] private AudioClip _sound;
private void PlaySound() {
_audio.PlaySoundAtTransform(_sound.name, transform);
}
A note about playing a sound with ref
Normally, when you play a sound with the above method, the sound will play once and then stop. If you'd like the sound to loop, or be able to stop the sound before the clip ends, you should use the PlaySoundAtTransformWithRef
or PlayGameSoundAtTransformWithRef
, and store the returned KMAudio.KMAudioRef
object. To stop the sound, call the StopSound
delegate:
private KMAudio _audio;
[SerializeField] private AudioClip _sound;
private IEnumerator PlaySound() {
var audioRef = _audio.PlaySoundAtTransformWithRef(_sound.name, transform);
yield return new WaitForSeconds(1);
audioRef.StopSound();
}
I can't hear my sounds in TestHarness!
In order for the sounds to play when using the above method, you need to add the audio file to the AudioClips
field of the Test Harness.
AudioSource
s directly
Using Unity You can also use AudioSource
to play sounds, which may be useful as this makes it easier to dynamically change the sound's volume, speed, and other properties. A downside to doing this is that these are unaffected by in-game volume settings.
To fix this, we can access the player settings to find the volume at the start of the bomb, and then subscribe to the OnInteract
event on each button controlling the sound effects volume in the menu dossier to determine when we should update this volume. Note that to do this, we need to first import the game's assemblies.
using Assets.Scripts.Settings; // PlayerSettingsManager
using Assets.Scripts.DossierMenu; // SoundMenuPage
public class ModuleModule : MonoBehaviour
{
// ...
[SerializeField] private AudioSource _audioSource;
private SoundMenuPage _soundMenu;
// ...
private void Awake() {
// ...
// We should only do this in-game. In the editor, we should just use a default volume which we can set in the Inspector
if (!Application.isEditor) {
_soundMenu = SceneManager.Instance.GameplayState.Room.MainMenu.SoundMenuPage;
// Update our volume whenever the player changes the volume setting
_soundMenu.SfxEntryLeft.OnInteract += HandleSFXVolumeChange;
_soundMenu.SfxEntryRight.OnInteract += HandleSFXVolumeChange;
// Call UpdateVolume to grab the initial volume
UpdateVolume();
}
}
private bool HandleSFXVolumeChange() {
// Wait a short time to make sure the volume value has been updated before we access it
Invoke(nameof(UpdateVolume), .05f);
return false;
}
private void UpdateVolume() => _audioSource.volume = PlayerSettingsManager.Instance.PlayerSettings.SFXVolume / 100f;
private void OnDestroy() {
if (!Application.isEditor) {
// Unsubscribe from the event to prevent exceptions from being thrown if the volume is changed after the bomb has been destroyed
_soundMenu.SfxEntryLeft.OnInteract -= HandleSFXVolumeChange;
_soundMenu.SfxEntryRight.OnInteract -= HandleSFXVolumeChange;
}
}
// ...
}