show objects and playerprefs

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
8676540--1169463--upload_2022-12-20_18-15-38.png

using System.Runtime.Serialization;
using UnityEngine;

public class ObjectManager : MonoBehaviour
{
    public GameObject[] objectsToManage; // Array of objects to manage
    private GameObject activeObject; // Current active object
    private int lastClickedIndex = -1; // Index of the last clicked button

    private void Start()
    {
        // Checking the saved state of objects when the scene starts
        for (int i = 0; i < objectsToManage.Length; i++)
        {
            int objectActiveState = PlayerPrefs.GetInt("Object" + i + "_ActiveState", 0);
            objectsToManage[i].SetActive(objectActiveState == 1); // Setting object activity according to the saved state
        }
    }

    private void SaveObjectStates()
    {
        for (int i = 0; i < objectsToManage.Length; i++)
        {
            PlayerPrefs.SetInt("Object" + i + "_ActiveState", objectsToManage[i].activeSelf ? 1 : 0);
        }
        PlayerPrefs.Save();
    }

    public void ToggleObjectActive(int objectIndex)
    {
        if (objectIndex >= 0 && objectIndex < objectsToManage.Length)
        {
            GameObject objectToToggle = objectsToManage[objectIndex];
            if (lastClickedIndex == objectIndex)
            {
                // If the same button is clicked, deactivate all objects
                DeactivateAllObjects();
                lastClickedIndex = -1; // Reset the last index
            }
            else
            {
                // Deactivate the previous active object
                if (activeObject != null)
                {
                    activeObject.SetActive(false);
                }

                // Activate the new object
                objectToToggle.SetActive(true);
                activeObject = objectToToggle;
                lastClickedIndex = objectIndex; // Save the last index
            }
            SaveObjectStates();
        }
        else
        {
            Debug.LogError("Invalid object index!");
        }
    }

    private void DeactivateAllObjects()
    {
        foreach (GameObject obj in objectsToManage)
        {
            obj.SetActive(false);
        }
        activeObject = null; // Update the current active object
    }

    private void OnApplicationQuit()
    {
        SaveObjectStates();
    }
}

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.

2 Likes

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:

public void ToggleObjectActive2(int objectIndex)
    {
        if (objectIndex >= 0 && objectIndex < objectsToManage.Length)
        {   
            GameObject objectToToggle = objectsToManage[objectIndex];
            var newState = !objectToToggle.activeSelf;
            DeactivateAllObjects();
            objectToToggle.SetActive(newState);
            activeObject = objectToToggle.activeSelf? objectToToggle : null;
       
            SaveObjectStates();
        }
        else
        {
            Debug.LogError("Invalid object index!");
        }
    }

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?
8676540--1169463--upload_2022-12-20_18-15-38.png

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
8676540--1169463--upload_2022-12-20_18-15-38.png

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
8676540--1169463--upload_2022-12-20_18-15-38.png

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.

private void Start()
{
    for (int i = 0; i < objectsToManage.Length; i++)
    {
        string path = Path.Combine(Application.persistentDataPath, $"Object{i}_ActiveState.txt");
        if (File.Exists(filePath))
        {
            string state = File.ReadAllText(path);
            objectsToManage[i].SetActive(state == "true");
        }
    }
}

private void SaveObjectStates()
{
    for (int i = 0; i < objectsToManage.Length; i++)
    {
        string path = Path.Combine(Application.persistentDataPath, $"Object{i}_ActiveState.txt");
        string state = objectsToManage[i].activeSelf ? "true" : "false";
        File.WriteAllText(path, state);
    }
}