Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question show objects and playerprefs

Discussion in 'Scripting' started by Pandausers, Mar 20, 2024.

  1. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    i created a script that displays an array of objects by their index and stores them in playerprefs when a button is clicked, but the problem is that indexes 1 and 2 work in reverse, for example when i click on a button that should activate an object with index 1, it activates the object with index 2 and the same with the second button
    upload_2024-3-21_0-24-50.png

    Code (CSharp):
    1. using System.Runtime.Serialization;
    2. using UnityEngine;
    3.  
    4. public class ObjectManager : MonoBehaviour
    5. {
    6.     public GameObject[] objectsToManage; // Array of objects to manage
    7.     private GameObject activeObject; // Current active object
    8.     private int lastClickedIndex = -1; // Index of the last clicked button
    9.  
    10.     private void Start()
    11.     {
    12.         // Checking the saved state of objects when the scene starts
    13.         for (int i = 0; i < objectsToManage.Length; i++)
    14.         {
    15.             int objectActiveState = PlayerPrefs.GetInt("Object" + i + "_ActiveState", 0);
    16.             objectsToManage[i].SetActive(objectActiveState == 1); // Setting object activity according to the saved state
    17.         }
    18.     }
    19.  
    20.     private void SaveObjectStates()
    21.     {
    22.         for (int i = 0; i < objectsToManage.Length; i++)
    23.         {
    24.             PlayerPrefs.SetInt("Object" + i + "_ActiveState", objectsToManage[i].activeSelf ? 1 : 0);
    25.         }
    26.         PlayerPrefs.Save();
    27.     }
    28.  
    29.     public void ToggleObjectActive(int objectIndex)
    30.     {
    31.         if (objectIndex >= 0 && objectIndex < objectsToManage.Length)
    32.         {
    33.             GameObject objectToToggle = objectsToManage[objectIndex];
    34.             if (lastClickedIndex == objectIndex)
    35.             {
    36.                 // If the same button is clicked, deactivate all objects
    37.                 DeactivateAllObjects();
    38.                 lastClickedIndex = -1; // Reset the last index
    39.             }
    40.             else
    41.             {
    42.                 // Deactivate the previous active object
    43.                 if (activeObject != null)
    44.                 {
    45.                     activeObject.SetActive(false);
    46.                 }
    47.  
    48.                 // Activate the new object
    49.                 objectToToggle.SetActive(true);
    50.                 activeObject = objectToToggle;
    51.                 lastClickedIndex = objectIndex; // Save the last index
    52.             }
    53.             SaveObjectStates();
    54.         }
    55.         else
    56.         {
    57.             Debug.LogError("Invalid object index!");
    58.         }
    59.     }
    60.  
    61.     private void DeactivateAllObjects()
    62.     {
    63.         foreach (GameObject obj in objectsToManage)
    64.         {
    65.             obj.SetActive(false);
    66.         }
    67.         activeObject = null; // Update the current active object
    68.     }
    69.  
    70.     private void OnApplicationQuit()
    71.     {
    72.         SaveObjectStates();
    73.     }
    74. }
    75.  
     
  2. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,562
    PlayerPrefs is really not a good solution for this. On Windows, they are written to the registry. It's got a limited size.

    Do yourself a favor and move to JSON, stored in files, in the user's preferred Application.persistentDataPath, which will keep the order consistent and support more data types.
     
    Ryiah and spiney199 like this.
  3. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,936
    Your code is working for me. But activeObject and lastClickedIndex would not be set when re-entering playmode. But why even keep track of lastClickedIndex?

    Seems the code could be simplified to:
    Code (csharp):
    1.  
    2. public void ToggleObjectActive2(int objectIndex)
    3.     {
    4.         if (objectIndex >= 0 && objectIndex < objectsToManage.Length)
    5.         {  
    6.             GameObject objectToToggle = objectsToManage[objectIndex];
    7.             var newState = !objectToToggle.activeSelf;
    8.             DeactivateAllObjects();
    9.             objectToToggle.SetActive(newState);
    10.             activeObject = objectToToggle.activeSelf? objectToToggle : null;
    11.        
    12.             SaveObjectStates();
    13.         }
    14.         else
    15.         {
    16.             Debug.LogError("Invalid object index!");
    17.         }
    18.     }
    19.  
     
    Last edited: Mar 20, 2024
  4. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    I'm currently using player prefs because I'm just learning. in the future, when the game is released, will it be necessary to store all this in the database, or is it possible to use JSON as well?
    upload_2024-3-21_10-44-37.png
     
  5. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    lastClickedIndex is responsible for controlling depending on how many times the button was clicked so that the object is activated or deactivated after more than 1 click
    upload_2024-3-21_10-46-19.png
     
  6. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    I'm sorry, I just didn't see the problem in my Unity inspector, so the code works as it should and has no problems
    upload_2024-3-21_19-9-18.png
     
  7. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,694
    It's dependent on whether you're comfortable with the user having access to the data. A database is typically for when you want to keep the data out of the hands of the user, and a local file in a format like JSON is for when you don't care and just want to store some data.

    Incidentally here is the simplest implementation for JSON. It's not the best approach since it's saving it to individual files but it's the simplest equivalent to PlayerPrefs.

    Code (csharp):
    1. private void Start()
    2. {
    3.     for (int i = 0; i < objectsToManage.Length; i++)
    4.     {
    5.         string path = Path.Combine(Application.persistentDataPath, $"Object{i}_ActiveState.txt");
    6.         if (File.Exists(filePath))
    7.         {
    8.             string state = File.ReadAllText(path);
    9.             objectsToManage[i].SetActive(state == "true");
    10.         }
    11.     }
    12. }
    13.  
    14. private void SaveObjectStates()
    15. {
    16.     for (int i = 0; i < objectsToManage.Length; i++)
    17.     {
    18.         string path = Path.Combine(Application.persistentDataPath, $"Object{i}_ActiveState.txt");
    19.         string state = objectsToManage[i].activeSelf ? "true" : "false";
    20.         File.WriteAllText(path, state);
    21.     }
    22. }
     
    Last edited: Mar 21, 2024