Search Unity

[ SOLVED ] PlayerPrefs Sound Play Problem

Discussion in 'Scripting' started by Deleted User, Jan 10, 2020.

  1. Deleted User

    Deleted User

    Guest

    Hello,

    I check my PlayerPrefs using the following :
    Code (CSharp):
    1. if (PlayerPrefs.HasKey("FunctionToggleState"))
    2.         {
    3.             if (PlayerPrefs.GetInt("FunctionToggleState") > 0)
    4.                 toggleFunction.isOn = true;
    5.             else
    6.                 toggleFunction.isOn = false;
    7.         }
    and in the following toggle function, I have :
    Code (CSharp):
    1. public void ToggleFunctionButton()
    2.     {
    3.         if (toggleFunction.isOn)
    4.         {
    5.             PlayButtonSound();
    6.  
    7.             functionOnText.SetActive(true);
    8.             functionOffText.SetActive(false);
    9.  
    10.             // Save FunctionToggleState to PlayerPrefs
    11.  
    12.             PlayerPrefs.SetInt("FunctionToggleState", 1);
    13.             PlayerPrefs.Save();
    14.         }
    15.         else
    16.         {
    17.             PlayButtonSound();
    18.  
    19.             functionOnText.SetActive(false);
    20.             functionOffText.SetActive(true);
    21.  
    22.             // Save FunctionToggleState to PlayerPrefs
    23.  
    24.             PlayerPrefs.SetInt("FunctionToggleState", 0);
    25.             PlayerPrefs.Save();
    26.         }
    27.     }
    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 'ButtonClick' sound, even though I've not yet clicked the toggle, how might I fix this ?
     
  2. adi7b9

    adi7b9

    Joined:
    Feb 22, 2015
    Posts:
    181
    After you're checking PlayerPrefs you need to call the method who mute/unmute the sound.
     
  3. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    When are you calling ToggleFunctionButton() ?
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    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.)
    Code (csharp):
    1.  
    2. if (PlayerPrefs.HasKey("FunctionToggleState"))
    3. {
    4.     toggleFunction.isOn = PlayerPrefs.GetInt("FunctionToggleState") > 0;
    5. }
    6.  
    Code (csharp):
    1.  
    2. private bool lastState = false;
    3.  
    4. public void ToggleFunctionButton()
    5. {
    6.     if (toggleFunction.isOn == lastState) return;
    7.  
    8.     PlayButtonSound();
    9.  
    10.     functionOnText.SetActive(toggleFunction.isOn);
    11.     functionOffText.SetActive(!toggleFunction.isOn);
    12.  
    13.     // Save FunctionToggleState to PlayerPrefs
    14.  
    15.     PlayerPrefs.SetInt("FunctionToggleState", toggleFunction.isOn ? 1 : 0);
    16.     PlayerPrefs.Save();
    17.  
    18.     lastState = toggleFunction.isOn;
    19. }
    20.  
    But still this question remains:
     
  5. Deleted User

    Deleted User

    Guest

    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 :
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         CheckPlayerPrefs();
    4.     }
    5.  
    6.     // CheckPlayerPrefs function
    7.  
    8.     public void CheckPlayerPrefs()
    9.     {
    10.         // Check if PlayerPrefs has key FunctionToggleState, if not, assign Default value
    11.  
    12.         SetFunction(PlayerPrefs.GetInt("FunctionToggleState", 1) != 1 ? false : true);
    13.     }
    14.  
    15.     // ToggleFunctionClicked, called from the toggleFunction toggle
    16.  
    17.     public void ToggleFunctionClicked()
    18.     {
    19.         PlayButtonSound();
    20.  
    21.         SetFunction(PlayerPrefs.GetInt("FunctionToggleState", 1) != 1 ? true : false);
    22.     }
    23.  
    24.     // SetFunction ( accepts true || false ) and updates accordingly
    25.  
    26.     private void SetFunction(bool IsOn)
    27.     {
    28.         if (IsOn)
    29.         {
    30.             functionOnText.SetActive(true);
    31.             functionOffText.SetActive(false);
    32.  
    33.             // Assign and Save FunctionToggleState to PlayerPrefs
    34.  
    35.             PlayerPrefs.SetInt("FunctionToggleState", 1);
    36.             PlayerPrefs.Save();
    37.  
    38.             Debug.Log("On!");
    39.         }
    40.         else
    41.         {
    42.             functionOnText.SetActive(false);
    43.             functionOffText.SetActive(true);
    44.  
    45.             // Assign and Save FunctionToggleState to PlayerPrefs
    46.  
    47.             PlayerPrefs.SetInt("FunctionToggleState", 0);
    48.             PlayerPrefs.Save();
    49.  
    50.             Debug.Log("Off!");
    51.         }
    52.     }
     
    Last edited by a moderator: Jan 10, 2020
  6. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    This is completely redundant:
    Code (csharp):
    1.  
    2. ? true : false
    3.  
     
  7. Deleted User

    Deleted User

    Guest

    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
    Code (CSharp):
    1. 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 ?
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class ToggleFunction1 : MonoBehaviour
    5. {
    6.     [Header("Toggle References")]
    7.  
    8.     public Toggle toggleFunction;
    9.     public GameObject functionOnText, functionOffText;
    10.  
    11.     [Header("UI | Sound")]
    12.  
    13.     public AudioClip buttonSound;
    14.  
    15.     private void Start()
    16.     {
    17.         if (PlayerPrefs.HasKey("ToggleState"))
    18.         {
    19.             if (PlayerPrefs.GetInt("ToggleState") == 1)
    20.                 toggleFunction.isOn = true;
    21.             else
    22.                 toggleFunction.isOn = false;
    23.         }
    24.     }
    25.  
    26.     public void FunctionEnable()
    27.     {
    28.         if (toggleFunction.isOn == true)
    29.         {
    30.             PlayerPrefs.SetInt("ToggleState", 1);
    31.  
    32.             PlayButtonSound();
    33.  
    34.             functionOnText.SetActive(true);
    35.             functionOffText.SetActive(false);
    36.         }
    37.         else
    38.         {
    39.             PlayerPrefs.SetInt("ToggleState", 0);
    40.  
    41.             PlayButtonSound();
    42.  
    43.             functionOnText.SetActive(false);
    44.             functionOffText.SetActive(true);
    45.         }
    46.  
    47.         PlayerPrefs.Save();
    48.     }
    49.  
    50.     // Called from any button requiring 'button click sound' when pressed
    51.  
    52.     public void PlayButtonSound()
    53.     {
    54.         // Play button click sound
    55.  
    56.         AudioSource source = gameObject.AddComponent<AudioSource>();
    57.         source.clip = buttonSound;
    58.         source.Play();
    59.  
    60.         // Destroy AudioSource after source.clip.length has been reached
    61.  
    62.         Destroy(source, source.clip.length);
    63.     }
    64. }
     
    Last edited by a moderator: Jan 12, 2020
  8. Deleted User

    Deleted User

    Guest

    ? 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 ?
     
    Last edited by a moderator: Jan 11, 2020
  9. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    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.
     
  10. Deleted User

    Deleted User

    Guest

    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... :mad:
     
    Last edited by a moderator: Jan 12, 2020
  11. Deleted User

    Deleted User

    Guest

    My word, that was perplexing ... :eek:

    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 !

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class ToggleFunction : MonoBehaviour
    5. {
    6.     [Header("Toggle References")]
    7.  
    8.     public Toggle toggleFunction;
    9.     public GameObject functionOnText, functionOffText;
    10.  
    11.     private void Start()
    12.     {
    13.         if (PlayerPrefs.HasKey("ToggleState"))
    14.         {
    15.             if (PlayerPrefs.GetInt("ToggleState") == 1)
    16.                 toggleFunction.isOn = true;
    17.             else
    18.                 toggleFunction.isOn = false;
    19.         }
    20.     }
    21.  
    22.     public void FunctionEnable()
    23.     {
    24.         if (toggleFunction.isOn == true)
    25.         {
    26.             PlayerPrefs.SetInt("ToggleState", 1);
    27.  
    28.             functionOnText.SetActive(true);
    29.             functionOffText.SetActive(false);
    30.         }
    31.         else
    32.         {
    33.             PlayerPrefs.SetInt("ToggleState", 0);
    34.  
    35.             functionOnText.SetActive(false);
    36.             functionOffText.SetActive(true);
    37.         }
    38.  
    39.         PlayerPrefs.Save();
    40.     }
    41. }
    And, the pointer event handling script, which I have attached to any button I want to play a button click sound on.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3.  
    4. public class ButtonSounds : MonoBehaviour, IPointerClickHandler
    5. {
    6.     [Header("UI | Button Sound")]
    7.  
    8.     public AudioClip buttonSound;
    9.  
    10.     // Detect if click occurs
    11.  
    12.     public void OnPointerClick(PointerEventData pointerEventData)
    13.     {
    14.         // If the user has clicked the left mouse button
    15.  
    16.         if (pointerEventData.button == PointerEventData.InputButton.Left)
    17.         {
    18.             // Call PlayButtonSound()
    19.  
    20.             PlayButtonSound();
    21.         }
    22.     }
    23.  
    24.     // Called from any button requiring 'button click sound' when pressed
    25.  
    26.     public void PlayButtonSound()
    27.     {
    28.         // Play button click sound
    29.  
    30.         AudioSource source = gameObject.AddComponent<AudioSource>();
    31.         source.clip = buttonSound;
    32.         source.Play();
    33.  
    34.         // Destroy AudioSource after source.clip.length has been reached
    35.  
    36.         Destroy(source, source.clip.length);
    37.     }
    38. }
    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.
     
    Last edited by a moderator: Jan 12, 2020