When saving and loading the player info state it's loading the position and rotation different why?

The state script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[Serializable]
public class SaveState
{
    public Vector3 pos { set; get; }
    public Quaternion rot { set; get; }
    public Vector3 scale { set; get; }

    public DateTime LastSaveTime { set; get; }
}

The manager script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.IO;
using System.Text;

public class SaveManager
{
    //Save Data
    public static void saveData<T>(T dataToSave, string dataFileName)
    {
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Convert To Json then to bytes
        string jsonData = JsonUtility.ToJson(dataToSave, true);
        byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);

        //Create Directory if it does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
        }
        //Debug.Log(path);

        try
        {
            File.WriteAllBytes(tempPath, jsonByte);
            Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
            Debug.LogWarning("Error: " + e.Message);
        }
    }

    //Load Data
    public static T loadData<T>(string dataFileName)
    {
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Exit if Directory or File does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Debug.LogWarning("Directory does not exist");
            return default(T);
        }

        if (!File.Exists(tempPath))
        {
            Debug.Log("File does not exist");
            return default(T);
        }

        //Load saved Json
        byte[] jsonByte = null;
        try
        {
            jsonByte = File.ReadAllBytes(tempPath);
            Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\"));
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\"));
            Debug.LogWarning("Error: " + e.Message);
        }

        //Convert to json string
        string jsonData = Encoding.ASCII.GetString(jsonByte);

        //Convert to Object
        object resultValue = JsonUtility.FromJson<T>(jsonData);
        return (T)Convert.ChangeType(resultValue, typeof(T));
    }

    public static bool deleteData(string dataFileName)
    {
        bool success = false;

        //Load Data
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Exit if Directory or File does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Debug.LogWarning("Directory does not exist");
            return false;
        }

        if (!File.Exists(tempPath))
        {
            Debug.Log("File does not exist");
            return false;
        }

        try
        {
            File.Delete(tempPath);
            Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\"));
            success = true;
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To Delete Data: " + e.Message);
        }

        return success;
    }
}

The test script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SaveTest : MonoBehaviour
{
    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.T))
        {
            var player = GameObject.Find("Player");
            SaveState saveData = new SaveState();
            saveData.pos = player.transform.localPosition;
            saveData.rot = player.transform.localRotation;
            saveData.scale = player.transform.localScale;

            //Save data from PlayerInfo to a file named players
            SaveManager.saveData(saveData, "players");


        }

        if(Input.GetKeyDown(KeyCode.L))
        {
            SaveState loadedData = SaveManager.loadData<SaveState>("players");
            if (loadedData == null)
            {
                return;
            }

            //Display loaded Data
            var player = GameObject.Find("Player");
            player.transform.localPosition = loadedData.pos;
            player.transform.localRotation = loadedData.rot;
            player.transform.localScale = loadedData.scale;
        }
    }
}

I’m using Find only for testing since the Player is on a different scene.

Anyway I’m running the game and pressing the T key at this point where the Player is in a middle of rotating coroutine and position :

You can see the Player position and rotation in the screenshot.

Then when the game continue a bit I press the L button to load it back and then I find that the Player here :

And since the Player position is not the same where saved it the Player is also falling down out the scene.
But the problem is that when it’s loading it’s loading the Player in a different position and different rotation.

I tried to save/load only with position/rotation or localPosition/localRotation in both cases same results.

Are you reading exact the same values what was written or different value, not what was written? Add Debug.Log for position when saving and loading into your save manager and post here what’s logged

Unity’s Json does not serialize properties, so it won’t save them.

1 Like

I changed it using binary formatter. But same results.

The SaveState class :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[Serializable]
public class SaveState
{
    public float posX;
    public float posY;
    public float posZ;

    public float rotX;
    public float rotY;
    public float rotZ;
    public float rotW;

    public float scaX;
    public float scaY;
    public float scaZ;

    public DateTime LastSaveTime { set; get; }
}

The manager :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.IO;

public class SaveManager : MonoBehaviour
{
    public static void Save(SaveState player)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.bin";
        FileStream stream = new FileStream(path, FileMode.Create);

        SaveState data = new SaveState();

        formatter.Serialize(stream, data);
        stream.Close();
    }

    public static SaveState Load()
    {
        string path = Application.persistentDataPath + "/player.bin";
        if (File.Exists(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(path, FileMode.Open);

            SaveState data = formatter.Deserialize(stream) as SaveState;
            stream.Close();

            return data;
        }
        else
        {
            Debug.LogError("Save file not found in " + path);
            return null;
        }
    }
}

And the test script :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SaveTest : MonoBehaviour
{
    public SaveManager saveManager;

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.T))
        {
            var player = GameObject.Find("Player");
            SaveState saveState = new SaveState();
            saveState.posX = player.transform.localPosition.x;
            saveState.posY = player.transform.localPosition.y;
            saveState.posZ = player.transform.localPosition.z;

            saveState.rotX = player.transform.localRotation.x;
            saveState.rotY = player.transform.localRotation.y;
            saveState.rotZ = player.transform.localRotation.z;
            saveState.rotW = player.transform.localRotation.w;

            saveState.scaX = player.transform.localScale.x;
            saveState.scaY = player.transform.localScale.y;
            saveState.scaZ = player.transform.localScale.z;

            //Save data from PlayerInfo to a file named players
            SaveManager.Save(saveState);


        }

        if(Input.GetKeyDown(KeyCode.L))
        {
            //Display loaded Data
            var player = GameObject.Find("Player");
            player.transform.localPosition = new Vector3(SaveManager.Load().posX, SaveManager.Load().posY, SaveManager.Load().posZ);
            player.transform.localRotation = new Quaternion(SaveManager.Load().rotX, SaveManager.Load().rotY, SaveManager.Load().rotZ, SaveManager.Load().rotW);
            player.transform.localScale = new Vector3(SaveManager.Load().scaX, SaveManager.Load().scaY, SaveManager.Load().scaZ);
        }
    }
}

Like before not errors or exceptions but when pressing on L to load it’s changing position and rotation like in the second screenshot.

I can see the player.bin 1 KB size file but it’s still not loading it fine.

As @palex-nx stated, put some debug.log statements in when saving and loading to see what is contained in the save data.