【问题标题】:Saving Cube like in Minecraft game像在 Minecraft 游戏中一样保存立方体
【发布时间】:2018-02-25 06:54:12
【问题描述】:

我正在尝试使用 Unity 为 Android 构建游戏,就像 Minecraft 一样。我怎样才能保存我的进度?

我正在尝试这段代码,但如果我走在正确的轨道上,我仍然一无所知。

public class SavePref : MonoBehaviour {

    GameObject[] objects;
     float x;
     float y;
     float z;

    // Use this for initialization
    void Start () {

        objects =  GameObject.FindGameObjectsWithTag("ObjectSnap");
    }   
    // Update is called once per frame
    void Update () {

    }

    public void Load()
    {
        foreach (GameObject obj in objects)
        {
            obj.name = PlayerPrefs.GetString("Ojects");
            x = PlayerPrefs.GetFloat("X");
            y = PlayerPrefs.GetFloat("Y");
            z = PlayerPrefs.GetFloat("Z");
        }
    }


    public void Save()
    {

        objects = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];

        Debug.Log(objects.Length);
        foreach (GameObject obj in objects)
        {
            PlayerPrefs.SetString("Objects", obj.name);
            Debug.Log(obj.name);
            x = obj.transform.position.x;
            PlayerPrefs.SetFloat("X", x);

            y = obj.transform.position.y;
            PlayerPrefs.SetFloat("Y", y);

            z = obj.transform.position.z;
            PlayerPrefs.SetFloat("Z", z);

            Debug.Log(obj.transform.position.x);
            Debug.Log(obj.transform.position.y);
            Debug.Log(obj.transform.position.z);
        }
    }
}

【问题讨论】:

  • 将 x,y,z 放入类或结构中,然后序列化并保存。示例见this 帖子
  • 哪个x、y、z? x,y,z 在 Save();?
  • 你想保存每个立方体的位置,对吧?使用类或结构来保存立方体的 x、y、z,然后创建该对象的数组/列表,序列化并保存它。您还可以将对象名称添加到该类/结构中

标签: c# android unity3d unity5 state-saving


【解决方案1】:

原因是你覆盖了相同的值。

场景中的每个对象都将覆盖 PlayerPerfs 的相同 'X' 'Y' 'Z' 和 'Objects' 变量。 因此,如果您只想保存块位置,
场景中的每个块都必须有自己的场景 ID。
当您编写 PlayerPerfs 时,请使用这些 ID。

例如:

public GameObject[] inscene;

void SaveBlock(){
    inscene = GameObject.FindGameObjectsWithType("ObjectSnap");

    for(int i = 0; i < inscene.Length; i++){
        PlayerPerfs.SetFloat(i.ToString() + "_x", x);
        PlayerPerfs.SetFloat(i.ToString() + "_y", y);
        PlayerPerfs.SetFloat(i.ToString() + "_z", z);
    }

    PlayerPerfs.SetInt("Count", inscene.Length);
}

void LoadBlocks(){
    int count = PlayerPerfs.GetInt("Count");
    inscene = new GameObject[count];

    for(int i = 0; i < count; i++)
    {
        float x = PlayerPerfs.GetFloat(i.ToString() + "_x");
        float y = PlayerPerfs.GetFloat(i.ToString() + "_y");
        float z = PlayerPerfs.GetFloat(i.ToString() + "_z");

        inscene[i] = GameObject.CreatePrimitive(PrimitiveType.Cube);
        inscene[i].transform.position = new Vector3(x, y, z);
        inscene[i].tag = "ObjectSnap";
    }
}

这段代码只会保存方块的位置,并用白色方块重新创建世界。

如果要保存块的类型,则应将所有类型的块作为预制件,并在 Load() 时实例化预制件。

附:无论如何,Android 版 Minecraft 克隆的这种实现是很糟糕的。 想象一下,你有一小块 (32*32*32) 的块,然后 RAM 将不得不处理内存中的 32768 个块(这只会杀死应用程序)。

因此,您必须操作的不是块,而是这些块的侧面,以剔除不可见的侧面。

而且您不应该通过 PlayerPerfs 保存场景信息。请改用 System.IO。据我所知,PlayerPerfs 将信息保存在注册表中,这对此类数据不利。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 2014-05-18
    • 2017-05-19
    • 2018-04-10
    相关资源
    最近更新 更多