对象的位置和旋转未被保存/加载(Unity 引擎)

Object's position & rotation is not getting saved / loaded (Unity Engine)

我需要保存玩家在游戏中的位置和旋转。为此,我使用 Binary Formatter 和 2 个按钮:'Save' 和 'Load'。如果我手动记下脚本保存 public Vector3 数据,保存它,然后再次加载场景。然而,玩家(只是一个立方体)不会改变它的位置和旋转。为了解决这个问题,我添加了:

void FixedUpdate()
    {
        position = player.transform.position;
        rotation = player.transform.rotation;
    } 

但这并没有帮助。我使用 2 个脚本来完成这项工作:

Player.cs

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

public class Player : MonoBehaviour
{
    public GameObject player;
    public Vector3 position;
    public Quaternion rotation;

    void FixedUpdate()
    {
        position = player.transform.position;
        rotation = player.transform.rotation;
    }

    public void Save()
    {
        SaveLoadManager.SavePlayer(this);
    }

    public void Load()
    {
        float[] loadedStats = SaveLoadManager.LoadPlayer();

        Vector3 loadedPos = new Vector3(loadedStats[0], loadedStats[1], loadedStats[2]);
        Vector3 loadedRot = new Vector3(loadedStats[3], loadedStats[4], loadedStats[5]);

        player.transform.position = loadedPos;
        player.transform.rotation = Quaternion.Euler(loadedRot);
    }
}

SaveLoadManager.cs

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

public static class SaveLoadManager
{
    public static void SavePlayer(Player player)
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream stream = new FileStream(Application.persistentDataPath + "/player.save", FileMode.Create);

        PlayerData data = new PlayerData(player);

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

    public static float[] LoadPlayer()
    {
        if (File.Exists(Application.persistentDataPath + "/player.save"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream stream = new FileStream(Application.persistentDataPath + "/player.save", FileMode.Open);

            PlayerData data = bf.Deserialize(stream) as PlayerData;

            stream.Close();
            return data.stats;
        }
        else
        {
            Debug.LogError("File does not exist.");
            return new float[6];
        }
    }
}

[Serializable]
public class PlayerData
{
    public float[] stats;

    public PlayerData(Player player)
    {
        stats = new float[6];

        stats[0] = player.position.x;
        stats[1] = player.position.y;
        stats[2] = player.position.z;

        stats[3] = player.rotation.x;
        stats[4] = player.rotation.y;
        stats[5] = player.rotation.z;
    }
}

我对保存-加载系统和二进制格式很陌生,所以我希望你能帮助我。

提前致谢!

如果其他人遇到类似问题:除了在下面的答案中添加代码外,我还更改了player.transform.rotation.(x/y/z);至 player.transform.eulerAngles.(x/y/z);在 SaveLoadManager.cs 中进行轮换。

我不确定我是否遗漏了什么,但我在您的 Load() 方法中没有看到任何地方实际将玩家的位置设置为加载的值。相反,看起来您正在将加载的值传递给不必要的变量,然后在 FixedUpdate() 中不断覆盖它们。

也许可以试试:

   public void Load()
    {
        float[] loadedStats = SaveLoadManager.LoadPlayer();
        
        Vector3 loadedPos = new Vector3(loadedStats[0], loadedStats[1], loadedStats[2]);
        Vector3 loadedRot = new Vector3(loadedStats[3], loadedStats[4], loadedStats[5]);
        player.transform.position = loadedPos ;
        player.transform.rotation = Quaternion.Euler(loadedRot);

    }

而且你可以去掉 Player 脚本中的位置和旋转变量。