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
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.
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?
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?
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
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);
}
}