Сохранение куба, как в игре Minecraft

Я пытаюсь создать игру для Android, как Minecraft, используя Unity. Как я могу сохранить свой прогресс?

Я пытаюсь этот код, но я все еще не знаю, если я на правильном пути.

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);
        }
    }
}

1 ответ

Причина в том, что вы перезаписываете одни и те же значения.

Каждый объект в сцене будет перезаписывать одинаковые переменные "X", "Y", "Z" и "Objects" PlayerPerfs. Итак, если вы хотите сохранить только позиции блоков,
каждый блок в сцене должен иметь свой собственный идентификатор сцены.
Когда вы пишете PlayerPerfs, используйте эти идентификаторы.

Например:

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 ().

PS Во всяком случае, такая реализация клона Minecraft для Android ужасна. Представьте себе, у вас есть один маленький блок (32*32*32), полный блоков, тогда ОЗУ будет обрабатывать 32768 блоков в памяти (которые просто убивают приложение).

Таким образом, вы должны управлять не блоками, а сторонами этих блоков, чтобы отбраковать стороны, которые не видны.

И вы не должны сохранять информацию о сцене через PlayerPerfs. Вместо этого используйте System.IO. Как я знаю, PlayerPerfs сохраняет информацию в реестре, что не подходит для таких данных.

Другие вопросы по тегам