对象的位置和旋转未被保存/加载(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 脚本中的位置和旋转变量。
我需要保存玩家在游戏中的位置和旋转。为此,我使用 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 脚本中的位置和旋转变量。