C# 如何保存和加载用户创建的游戏对象?

C# 如何保存和加载用户创建的游戏对象?,c#,object,unity3d,save,load,C#,Object,Unity3d,Save,Load,我已经实现了用户可以选择定制3D对象的所有选项,并添加了一些GUI按钮来改进我的旧代码,提高可用性。但我在弄清楚如何保存和加载游戏对象时遇到了一些麻烦 我读过关于序列化的文章,看到一些人提到PlayerRefs,但我仍然无法理解如何在对象中使用它 using System.Collections; using System.Collections.Generic; using UnityEngine; public class cubeControls : MonoBehaviour

我已经实现了用户可以选择定制3D对象的所有选项,并添加了一些GUI按钮来改进我的旧代码,提高可用性。但我在弄清楚如何保存和加载游戏对象时遇到了一些麻烦

我读过关于序列化的文章,看到一些人提到PlayerRefs,但我仍然无法理解如何在对象中使用它

 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"))
         {
         }
     }
 }
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类立方体控件:单行为
{
//对象旋转的常数
公共浮子移动速度=80.0F;
公共浮子转速=100.0F;
//原始立方体的初始比例
公共静态Vector3 initscale=Vector3.1;
//在第一帧更新之前调用Start
void Start()
{
}
//每帧调用一次更新
无效更新()
{
//更改对象的位置
//将对象向右移动
if(Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right*moveSpeed*Time.deltaTime);
}
//将对象向左移动
if(Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left*moveSpeed*Time.deltaTime);
}
//更改对象的旋转
//向右旋转立方体
if(Input.GetKey(KeyCode.RightArrow))
{
变换。旋转(矢量3.up,转速*时间。增量时间);
}
//向左旋转立方体
if(Input.GetKey(KeyCode.LeftArrow))
{
变换.旋转(矢量3.down,转速*时间.deltaTime);
}
//保存当前渲染的材质
渲染器rend=GetComponent();
//更改对象的比例
//将立方体的大小增加一倍
if(Input.GetKeyDown(KeyCode.Alpha2))
{
transform.localScale+=新矢量3(2F,2F,2F);
}
//通过按键改变颜色
if(Input.GetKeyDown(KeyCode.R))
{
rend.material.SetColor(“U颜色”,颜色为红色);
}
}
//将按钮元素添加到可视化界面的步骤
void OnGUI()
{
//换汽缸
if(GUI.按钮(新矩形(50、90、100、40),“圆柱体”))
{
GameObject newCylinder=GameObject.CreatePrimitive(PrimitiveType.Cylinder);
newCylinder.AddComponent();
摧毁(游戏对象);
}
//拯救
if(GUI.按钮(新矩形(700、330、50、30),“保存”))
{
}
//装载
if(GUI.按钮(新矩形(770、330、50、30),“加载”))
{
}
}
}

您无法保存游戏对象。您保存的唯一内容是游戏对象的详细信息。例如,如果有具有某些粒子效果的三维立方体,则首先保存立方体的所需值,如位置、旋转、比例、颜色和其他必要元素(需要更改的粒子发射器值)。即使在序列化中,您也无法保存Vector3,因为它是一个结构,必须为向量编写自己的序列化程序。简言之,您在游戏对象工作所需的值和其他需要用户/其他系统自定义输入的行为特征中保存的内容。可以将其视为通过保存和加载影响对象的变量的状态,将对象重建到您停止的状态的一种方法

Unity保存有两种类型

1) :使用player prefs,您一次只能在字段中保存一个值。通常是三者之一:

  • 浮动
  • Int
您通常保存令牌和其他不需要大文件的小值

2) 序列化的游戏数据:在这里,您可以将大型数据集和类(如PlayerInfo)保存在序列化文件中,以自定义方式更改场景

我相信你要找的是第二个。因此,与其寻找所有的示例并感到困惑,不如从在文件中保存/加载多维数据集值(可能是位置?或运行时修改的任何内容)开始。逐渐地,您可以切换到序列化程序

您可以查看以下链接以帮助进一步了解


此保存代码段来自简单的二进制格式化程序链接,该链接保存某些类型的整数列表和用户分数

[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");
}
[System.Serializable]
公共类保存
{
public List livingTargetPositions=新列表();
public List livingTargetsTypes=new List();
公共整数命中率=0;
公共int shots=0;
}
私有保存CreateSaveGameObject()
{
保存=新保存();
int i=0;
foreach(游戏对象目标中的游戏对象)
{
Target=targetGameObject.GetComponent();
if(target.activeRobot!=null)
{
save.livingTargetPositions.Add(target.position);
save.livingTargetsTypes.Add((int)target.activeRobot.GetComponent().type);
i++;
}
}
save.hits=点击次数;
save.shots=快照;
返回保存;
}
公共存储游戏()
{
// 1
Save Save=CreateSaveGameObject();
// 2
BinaryFormatter bf=新的BinaryFormatter();
FileStream file=file.Create(Application.persistentDataPath+“/gamesave.save”);
序列化(文件,保存);
file.Close();
// 3
点击率=0;
镜头=0;
shotsText.text=“快照:”+快照;
hitsText.text=“点击次数:”+点击次数;
ClearRobots();
ClearBullets();
Debug.Log(“游戏已保存”);
}

感谢您的详细解释!好的,所以我使用序列化、PlayerPrefs和JSON以字符串的形式保存了位置坐标(x、y、z)。我已经确认它们确实保存在字符串中,并且字符串不是空的,但是如何获取这些值并重新绘制3D对象?因为无法保存三维对象的形状