The PlayerPrefs class of Unity does not have a specific method to store vectors, however it has three functions that allow to store data of type integer, float and strings, the types of variable int and float are known as primitive variables and with them it is possible to reconstruct other more complex data structures, and is that a vector of R2 or R3, if we think about it, is nothing more than an array of three variables of type float, that each one occupies a position or has a meaning.
Unity package to download with implemented solution
Below you can download the Unity package with the example we are going to analyze in this article, so you can import it and test it directly on your own computer.
Analysis on how to save a Vector3 with PlayerPrefs
The basic idea is to decompose the vector into its components that are float data and then store those components individually with PlayerPrefs, then, when loading the data, retrieve each component from memory and create a new vector using those components.
In the scene that comes in the download package the solution is already assembled, in figure 2 we see how the hierarchy is composed, we have a GameObject called “SaveDataScript” which is the one that has assigned the Script that we are going to analyze (see figure 3) and this is responsible for saving and loading data. Then we have another GameObject called “ObjectToSavePosition” that is a cube to which we will save its position to be able to load it when starting the scene. Notice that in the inspector in figure 3, our Script has a reference to this object, this will allow you to read and modify its variables or execute functions on this GameObject,
I always insist that understanding the concept of reference in programming is a very important pillar in the development of applications with Unity, in this link you will find a playlist of my channel about references in programming and different methods to find them.
Script that is responsible for saving and loading the vector
In figure 4 we see a part of the data saving script that comes in the package, we can see the GameObject type variable called “objectWithSavedPosition” that appears in the inspector in figure 3 and also the Awake and Start methods, which are functions use for initialization that Unity executes automatically at different times within the life cycle of the application. Inside the Awake function is executed a custom function called “LoadData” which is responsible for loading the information, this “LoadData” function is defined by ourselves, we see it later.
The data loading is something that normally happens when starting a scene, sometimes problems can arise depending on where the data loading is done, remember that the Start functions are executed one after another for each GameObject in an order that we can not predict or that would be tedious to predict, imagine that a Script in its Start function uses variables from another Script that has not yet loaded its data!
En los juegos se suelen tener atajos para guardado y carga rápida, en la figura 5 tenemos unas instrucciones que hacen precisamente esto, noten que al presionar F5 se ejecuta una función llamada “SaveData” que se encarga de hacer el guardado, sería conveniente que el guardado de todas las variables necesarias se haga dentro de esa función o que en el interior se llamen a otras funciones que se encarguen de guardar otros datos, de esa forma una vez que ejecutamos la instrucción SaveData estamos seguros de que toda la información se ha guardado, lo mismo para la función “LoadData” que se encarga de leer los datos guardados en la memoria e inicializar las variables con esos datos.
In games we usually have shortcuts for saving and fast loading, in figure 5 we have some instructions that do just this, notice that when pressing F5 a function called “SaveData” is executed that is in charge of saving all the relevant information and the same for the “LoadData” function when pressing F8.
Example on how to save a Vector3 using PlayerPrefs
Figure 6 shows the content of the SaveData function, which is responsible for saving the vector data that will later allow us to reconstruct it. Note that first a decomposition of the vector to be saved is made in its X, Y and Z variables, which are stored in the temporary variables “positionX”, “positionY” and “positionZ”.
The saving of data with PlayerPrefs is done in the last three instructions, using the “SetFloat” function from PlayerPrefs,note the name that is passed as a label of these saves, these names must be used in the data load to retrieve them.
Example on how to load a Vector3 using PlayerPrefs
Figure 7 shows the content of the LoadData function that is responsible for loading the data stored in memory and make a reconstruction of the vector, the load is the reverse process, first we retrieve the data from memory, we do this with the “GetFloat” function from PlayerPrefs, passing the label that was used for each data and in this example I include the value 0 in case there is no previously stored information, this allows us to call it directly in Start or Awake and to make sure there are no conflicts the first time the application is run.
The next instruction is in charge of creating Vector3 from the data retrieved from memory. Vector3 and in general most classes have constructors that allow us to create the data by giving them initial values, we use that constructor with the “new” keyword.
The problem does not end here, as we have read the information, create the vector but we have not yet told our GameObject to position itself on that Vector3 coordinate, this is done in the last instruction in Figure 7.