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.

Using Unity AudioSources directly

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;
        }
    }
// ...
}