[ SOLVED ] PlayerPrefs Sound Play Problem

Hello,

I check my PlayerPrefs using the following :

if (PlayerPrefs.HasKey("FunctionToggleState"))
        {
            if (PlayerPrefs.GetInt("FunctionToggleState") > 0)
                toggleFunction.isOn = true;
            else
                toggleFunction.isOn = false;
        }

and in the following toggle function, I have :

public void ToggleFunctionButton()
    {
        if (toggleFunction.isOn)
        {
            PlayButtonSound();

            functionOnText.SetActive(true);
            functionOffText.SetActive(false);

            // Save FunctionToggleState to PlayerPrefs

            PlayerPrefs.SetInt("FunctionToggleState", 1);
            PlayerPrefs.Save();
        }
        else
        {
            PlayButtonSound();

            functionOnText.SetActive(false);
            functionOffText.SetActive(true);

            // Save FunctionToggleState to PlayerPrefs

            PlayerPrefs.SetInt("FunctionToggleState", 0);
            PlayerPrefs.Save();
        }
    }

It works fine enough, except, if I quit my application, then run it again, if I’ve left the toggle in the OFF state, it plays my ‘ButtonClicksound, even though I’ve not yet clicked the toggle, how might I fix this ?

After you’re checking PlayerPrefs you need to call the method who mute/unmute the sound.

When are you calling ToggleFunctionButton() ?

I’d remove the duplicate if and else statements to start with. And then, you’re calling play sound on every call to ToggleFunctionButton. You probably only want to do that if the state has changed. (And all the other things also only need to be done when there is a change.)

if (PlayerPrefs.HasKey("FunctionToggleState"))
{
    toggleFunction.isOn = PlayerPrefs.GetInt("FunctionToggleState") > 0;
}
private bool lastState = false;

public void ToggleFunctionButton()
{
    if (toggleFunction.isOn == lastState) return;

    PlayButtonSound();

    functionOnText.SetActive(toggleFunction.isOn);
    functionOffText.SetActive(!toggleFunction.isOn);

    // Save FunctionToggleState to PlayerPrefs

    PlayerPrefs.SetInt("FunctionToggleState", toggleFunction.isOn ? 1 : 0);
    PlayerPrefs.Save();

    lastState = toggleFunction.isOn;
}

But still this question remains:

Hi, this is the code I’ve been working with and where I currently am with it, I’ve been trying random stuff, but it’s still not working, I will look at all the suggestions everyone has posted and post back here if I fix it :

    void Start()
    {
        CheckPlayerPrefs();
    }

    // CheckPlayerPrefs function

    public void CheckPlayerPrefs()
    {
        // Check if PlayerPrefs has key FunctionToggleState, if not, assign Default value

        SetFunction(PlayerPrefs.GetInt("FunctionToggleState", 1) != 1 ? false : true);
    }

    // ToggleFunctionClicked, called from the toggleFunction toggle

    public void ToggleFunctionClicked()
    {
        PlayButtonSound();

        SetFunction(PlayerPrefs.GetInt("FunctionToggleState", 1) != 1 ? true : false);
    }

    // SetFunction ( accepts true || false ) and updates accordingly

    private void SetFunction(bool IsOn)
    {
        if (IsOn)
        {
            functionOnText.SetActive(true);
            functionOffText.SetActive(false);

            // Assign and Save FunctionToggleState to PlayerPrefs

            PlayerPrefs.SetInt("FunctionToggleState", 1);
            PlayerPrefs.Save();

            Debug.Log("On!");
        }
        else
        {
            functionOnText.SetActive(false);
            functionOffText.SetActive(true);

            // Assign and Save FunctionToggleState to PlayerPrefs

            PlayerPrefs.SetInt("FunctionToggleState", 0);
            PlayerPrefs.Save();

            Debug.Log("Off!");
        }
    }

This is completely redundant:

? true : false

Hey,
In the latest version of my script, the save / load functionality is working as I require, however, I still have the play sound problem if my button toggle state is false when I restart the game view. I have removed the PlayButtonSound();

function, looking for feedback on best place to call it, so it doesn’t automatically play if the user had toggled the function to false ?

using UnityEngine;
using UnityEngine.UI;

public class ToggleFunction1 : MonoBehaviour
{
    [Header("Toggle References")]

    public Toggle toggleFunction;
    public GameObject functionOnText, functionOffText;

    [Header("UI | Sound")]

    public AudioClip buttonSound;

    private void Start()
    {
        if (PlayerPrefs.HasKey("ToggleState"))
        {
            if (PlayerPrefs.GetInt("ToggleState") == 1)
                toggleFunction.isOn = true;
            else
                toggleFunction.isOn = false;
        }
    }

    public void FunctionEnable()
    {
        if (toggleFunction.isOn == true)
        {
            PlayerPrefs.SetInt("ToggleState", 1);

            PlayButtonSound();

            functionOnText.SetActive(true);
            functionOffText.SetActive(false);
        }
        else
        {
            PlayerPrefs.SetInt("ToggleState", 0);

            PlayButtonSound();

            functionOnText.SetActive(false);
            functionOffText.SetActive(true);
        }

        PlayerPrefs.Save();
    }

    // Called from any button requiring 'button click sound' when pressed

    public void PlayButtonSound()
    {
        // Play button click sound

        AudioSource source = gameObject.AddComponent<AudioSource>();
        source.clip = buttonSound;
        source.Play();

        // Destroy AudioSource after source.clip.length has been reached

        Destroy(source, source.clip.length);
    }
}

? Any ideas …

Is there a way to detect if my game is running for the first time after having been quit, I might be able to use a boolean conditional statement ?

Hmmm, could it be that you are adding the PlayButtonSound() event to the toggleFunction’s Toggle component? By that I mean, did you drag the PlayButtonSound() function in the toggle field in the inspector? If you did, it could be possible that your Start() is changing the value of the toggle from TRUE (default) to FALSE, thus calling the method that plays the sound?

Sorry if you didn’t understand this well enough. Please send a screenshot of your inspector when you select the actual toggleFunction if this didn’t help.

Thanks,

No, I haven’t added the sound as a click event. I only add the sound via script.

I have two states, on and off for the toggle. Depending on which state it is in, I then save that to PlayerPrefs.

If it’s in the ON state when I save, when I reload the game, the sound DOES NOT PLAY.
if it’s in the OFF state when I save, when I reload the game, the sound DOES PLAY.

I would assume, inside the editor, the toggle is on by default, when I run the game, it reads the PlayerPrefs and sees it should be in the OFF state, so sets’ isOn to initiate the ELSE part of the statement, and we hear my button click SOUND playing when the user runs the program the second time around, not ideal…

I could possibly get round this, in the Awake method, by muting the sound effects in my game for the length of time my button click sound would play for, and then reinstate the sound effects straight after that, but that just seems stupid and avoiding the problem… :rage:

My word, that was perplexing … :hushed:

Anyhow, I have it working now, using a different method. So, the ToggleFunction script is now completely seperate from the PlaySound function, and instead I call the PlaySound function from a pointer event handler script, that only plays if the user has pressed the button physically !

using UnityEngine;
using UnityEngine.UI;

public class ToggleFunction : MonoBehaviour
{
    [Header("Toggle References")]

    public Toggle toggleFunction;
    public GameObject functionOnText, functionOffText;

    private void Start()
    {
        if (PlayerPrefs.HasKey("ToggleState"))
        {
            if (PlayerPrefs.GetInt("ToggleState") == 1)
                toggleFunction.isOn = true;
            else
                toggleFunction.isOn = false;
        }
    }

    public void FunctionEnable()
    {
        if (toggleFunction.isOn == true)
        {
            PlayerPrefs.SetInt("ToggleState", 1);

            functionOnText.SetActive(true);
            functionOffText.SetActive(false);
        }
        else
        {
            PlayerPrefs.SetInt("ToggleState", 0);

            functionOnText.SetActive(false);
            functionOffText.SetActive(true);
        }

        PlayerPrefs.Save();
    }
}

And, the pointer event handling script, which I have attached to any button I want to play a button click sound on.

using UnityEngine;
using UnityEngine.EventSystems;

public class ButtonSounds : MonoBehaviour, IPointerClickHandler
{
    [Header("UI | Button Sound")]

    public AudioClip buttonSound;

    // Detect if click occurs

    public void OnPointerClick(PointerEventData pointerEventData)
    {
        // If the user has clicked the left mouse button

        if (pointerEventData.button == PointerEventData.InputButton.Left)
        {
            // Call PlayButtonSound()

            PlayButtonSound();
        }
    }

    // Called from any button requiring 'button click sound' when pressed

    public void PlayButtonSound()
    {
        // Play button click sound

        AudioSource source = gameObject.AddComponent<AudioSource>();
        source.clip = buttonSound;
        source.Play();

        // Destroy AudioSource after source.clip.length has been reached

        Destroy(source, source.clip.length);
    }
}

EDIT : I should also note that I only use this method on buttons that can be ‘toggled’ on and off, if it’s a standard button, such as ‘Play’ or a website link, etc, I just call the PlaySound function directly.