如何保存和加载用户创建的游戏对象?
How can I save and load the gameObject that the user creates?
我已经实现了用户可以选择的所有选项来自定义 3D 对象,并添加了一些 GUI 按钮来改进我的旧代码并提高可用性。但是我在弄清楚如何保存和加载游戏对象时遇到了一些麻烦。
我读过有关序列化的内容,并且看到有人提到了 PlayerPrefs,但我仍然无法理解如何将其用于对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cubeControls : MonoBehaviour
{
// Constants for object rotation
public float moveSpeed = 80.0F;
public float turnSpeed = 100.0F;
// Initial scale of the original cube
public static Vector3 initscale = Vector3.one;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// Changing the position of the object
// Moving the object right
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
}
// Moving the object left
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left * moveSpeed * Time.deltaTime);
}
// Changing the rotation of the object
// Rotating the cube to the right
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
}
// Rotating the cube to the left
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(Vector3.down, turnSpeed * Time.deltaTime);
}
// Saving the current rendered material
Renderer rend = GetComponent<Renderer>();
// Changing the scale of the object
// Double the size of the cube
if (Input.GetKeyDown(KeyCode.Alpha2))
{
transform.localScale += new Vector3(2F, 2F, 2F);
}
// Changing the color via key presses
if (Input.GetKeyDown(KeyCode.R))
{
rend.material.SetColor("_Color", Color.red);
}
}
// To add button elements to the visual interface
void OnGUI()
{
// Changing to cylinder
if (GUI.Button(new Rect(50, 90, 100, 40), "Cylinder"))
{
GameObject newCylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
newCylinder.AddComponent<cubeControls>();
Destroy(gameObject);
}
// Saving
if (GUI.Button(new Rect(700, 330, 50, 30), "Save"))
{
}
// Loading
if (GUI.Button(new Rect(770, 330, 50, 30), "Load"))
{
}
}
}
您无法保存游戏对象。您唯一保存的是游戏对象的详细信息。举个例子,如果你有一个带有一些粒子效果的 3D 立方体,你首先要保存立方体所需的值,如位置、旋转、比例、颜色和其他必要的元素(需要更改的粒子发射器值)。即使在序列化中,您也无法保存 Vector3,因为它是一个结构,必须为向量编写自己的序列化程序。简而言之,您保存的游戏对象工作所需的值以及其他需要用户/其他系统自定义输入的行为特征。将其视为通过保存和加载影响对象的变量状态来将对象重建到中断状态的方法。
Unity 保存有两种类型
1) Player prefs : 使用播放器首选项,您一次只能在字段中保存一个值。通常是三个之一:
- 浮动
- 整数
- 字符串
您通常保存令牌和其他不需要大文件的小值
2) 序列化游戏数据:在这里您可以保存大型数据集和 类,例如 PlayerInfo,在序列化文件中对场景进行自定义更改。
我相信你要找的是第二个。因此,与其查找所有示例并感到困惑,您真正可以从 saving/loading 文件中的多维数据集值(可能是位置?或您在运行时修改的任何内容)开始。逐渐地,您可以转向序列化程序。
您可以查看以下 link 以帮助您进一步了解。
Save/Load Data using simple BinaryFormatter
此保存片段来自简单的二进制格式化程序 link,它保存了某些类型和用户分数的整数列表。
[System.Serializable]
public class Save
{
public List<int> livingTargetPositions = new List<int>();
public List<int> livingTargetsTypes = new List<int>();
public int hits = 0;
public int shots = 0;
}
private Save CreateSaveGameObject()
{
Save save = new Save();
int i = 0;
foreach (GameObject targetGameObject in targets)
{
Target target = targetGameObject.GetComponent<Target>();
if (target.activeRobot != null)
{
save.livingTargetPositions.Add(target.position);
save.livingTargetsTypes.Add((int)target.activeRobot.GetComponent<Robot>().type);
i++;
}
}
save.hits = hits;
save.shots = shots;
return save;
}
public void SaveGame()
{
// 1
Save save = CreateSaveGameObject();
// 2
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
bf.Serialize(file, save);
file.Close();
// 3
hits = 0;
shots = 0;
shotsText.text = "Shots: " + shots;
hitsText.text = "Hits: " + hits;
ClearRobots();
ClearBullets();
Debug.Log("Game Saved");
}
我已经实现了用户可以选择的所有选项来自定义 3D 对象,并添加了一些 GUI 按钮来改进我的旧代码并提高可用性。但是我在弄清楚如何保存和加载游戏对象时遇到了一些麻烦。
我读过有关序列化的内容,并且看到有人提到了 PlayerPrefs,但我仍然无法理解如何将其用于对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cubeControls : MonoBehaviour
{
// Constants for object rotation
public float moveSpeed = 80.0F;
public float turnSpeed = 100.0F;
// Initial scale of the original cube
public static Vector3 initscale = Vector3.one;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// Changing the position of the object
// Moving the object right
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
}
// Moving the object left
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left * moveSpeed * Time.deltaTime);
}
// Changing the rotation of the object
// Rotating the cube to the right
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
}
// Rotating the cube to the left
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(Vector3.down, turnSpeed * Time.deltaTime);
}
// Saving the current rendered material
Renderer rend = GetComponent<Renderer>();
// Changing the scale of the object
// Double the size of the cube
if (Input.GetKeyDown(KeyCode.Alpha2))
{
transform.localScale += new Vector3(2F, 2F, 2F);
}
// Changing the color via key presses
if (Input.GetKeyDown(KeyCode.R))
{
rend.material.SetColor("_Color", Color.red);
}
}
// To add button elements to the visual interface
void OnGUI()
{
// Changing to cylinder
if (GUI.Button(new Rect(50, 90, 100, 40), "Cylinder"))
{
GameObject newCylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
newCylinder.AddComponent<cubeControls>();
Destroy(gameObject);
}
// Saving
if (GUI.Button(new Rect(700, 330, 50, 30), "Save"))
{
}
// Loading
if (GUI.Button(new Rect(770, 330, 50, 30), "Load"))
{
}
}
}
您无法保存游戏对象。您唯一保存的是游戏对象的详细信息。举个例子,如果你有一个带有一些粒子效果的 3D 立方体,你首先要保存立方体所需的值,如位置、旋转、比例、颜色和其他必要的元素(需要更改的粒子发射器值)。即使在序列化中,您也无法保存 Vector3,因为它是一个结构,必须为向量编写自己的序列化程序。简而言之,您保存的游戏对象工作所需的值以及其他需要用户/其他系统自定义输入的行为特征。将其视为通过保存和加载影响对象的变量状态来将对象重建到中断状态的方法。
Unity 保存有两种类型
1) Player prefs : 使用播放器首选项,您一次只能在字段中保存一个值。通常是三个之一:
- 浮动
- 整数
- 字符串
您通常保存令牌和其他不需要大文件的小值
2) 序列化游戏数据:在这里您可以保存大型数据集和 类,例如 PlayerInfo,在序列化文件中对场景进行自定义更改。
我相信你要找的是第二个。因此,与其查找所有示例并感到困惑,您真正可以从 saving/loading 文件中的多维数据集值(可能是位置?或您在运行时修改的任何内容)开始。逐渐地,您可以转向序列化程序。
您可以查看以下 link 以帮助您进一步了解。
Save/Load Data using simple BinaryFormatter
此保存片段来自简单的二进制格式化程序 link,它保存了某些类型和用户分数的整数列表。
[System.Serializable]
public class Save
{
public List<int> livingTargetPositions = new List<int>();
public List<int> livingTargetsTypes = new List<int>();
public int hits = 0;
public int shots = 0;
}
private Save CreateSaveGameObject()
{
Save save = new Save();
int i = 0;
foreach (GameObject targetGameObject in targets)
{
Target target = targetGameObject.GetComponent<Target>();
if (target.activeRobot != null)
{
save.livingTargetPositions.Add(target.position);
save.livingTargetsTypes.Add((int)target.activeRobot.GetComponent<Robot>().type);
i++;
}
}
save.hits = hits;
save.shots = shots;
return save;
}
public void SaveGame()
{
// 1
Save save = CreateSaveGameObject();
// 2
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
bf.Serialize(file, save);
file.Close();
// 3
hits = 0;
shots = 0;
shotsText.text = "Shots: " + shots;
hitsText.text = "Hits: " + hits;
ClearRobots();
ClearBullets();
Debug.Log("Game Saved");
}