Barto
Barto

Reputation: 47

How do I change the pitch of audio when slowing down time?

I've been making a game using Unity and I added a slow motion function. Afterwards, when I added audio, I wanted to change the pitch of all audio whenever the slow motion function ocurred, but I can't seem to do it. I've been using Brackey's audio tutorial (here if you wanna see it) to guide me into using audio in Unity

Here is my audio manager:

using UnityEngine.Audio;
using System;

public class soundManager : MonoBehaviour
{
    public Sound[] sounds;

    void Awake()
    {

        foreach(Sound s in sounds)
        {
            s.source = gameObject.AddComponent<AudioSource>();
            s.source.clip = s.clip;

            s.source.volume = s.volume;
            s.source.pitch = s.pitch;
        }

    }

    public void Play(string name)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        s.source.Play();
    }
}

here is my slow motion script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimeManager : MonoBehaviour
{

    public float slowdownFactor = 0.05f;
    public float slowdownLength = 2.0f;

    private void Update()
    {
        Time.timeScale += (1f / slowdownLength) * Time.unscaledDeltaTime;
        Time.timeScale = Mathf.Clamp(Time.timeScale, 0f, 1f);

    }

    public void DoSlowMotion()
    {
        Time.timeScale = slowdownFactor;
        Time.fixedDeltaTime = Time.timeScale * 0.02f;
    }

}

Upvotes: 1

Views: 2796

Answers (1)

IndieGameDev
IndieGameDev

Reputation: 2974

I wanted to change the pitch of all audio

If you want to change the pitch of any song at runtime you can simply use the source of type AudioSource that is saved in the sound class and edit it's values directly.

If you then do this as a foreach loop, in your soundManager class, with each song in your array, you can pitch down all of them.

Change All Pitch Values:

public void ChangeAllPitchValues(float pitchDifference) {
    // Loop through our whole sound array.
    foreach (Sound s in sounds) {
        // Adjust pitch value equal to the given difference.
        s.source.pitch += pitchDifference;
    }
}

Additionally it seems like you are missing the singleton pattern that Brackeys used. You should probably add that as well to easily call the soundManager from any other script including your TimeManager.

#region Singelton
public static soundManager instance;

private void Awake() {
    // Check if instance is already defined
    // and if this gameObject is not the current instance.
    if (instance != null) {
        Debug.LogWarning("Multiple instances found. Current instance was destroyed.");
        Destroy (gameObject);
        return;
    }

    instance = this;
    DontDestroyOnLoad(gameObject);

    foreach (Sound s in sounds) {
        s.source = gameObject.AddComponent<AudioSource>();
        s.source.clip = s.clip;
        s.source.volume = s.volume;
        s.source.pitch = s.pitch;
        s.source.loop = s.loop;
    }
}
#endregion


Once you've added the singleton pattern and the new function in the soundManager, then you can simply call that function from your DoSlowMotion() method.

Call the Method:

public void DoSlowMotion() {
    ...
    // Pitch all songs down to 0.95f instead of 1f.
    soundManager.instance.ChangeAllPitchValues(-slowdownFactor);
}

Upvotes: 1

Related Questions