Forum begins after the advertisement:

 


[Part 7] Map problem

  • This topic has 70 replies, 4 voices, and was last updated 1 year ago by MI NI.
Viewing 20 posts - 41 through 60 (of 71 total)
  • Author
    Posts
  • #15538
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    First. Change your MapManager.cs code to this:

        private void OnEnable()
        {
            SaveData.Instance.LoadMapData();
    
            UpdateMap();
        }

    This should make your maps load properly on start of the game and when you activate a save point.


    next

    Can you send your SaveData.cs code again? I suspect you forgot to delete some items off from the script that is retaining mapName information.

    I’ve tested out the method and overall it is able to save and delete just fine otherwise.

    #15539
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Okay, sorry to trouble you.

    Regarding the first question, I think my initial idea was wrong, which caused you to misunderstand my idea. Regarding this point, I am very concerned about the construction. I think I want to be like Hollow Knight, and only update when interacting with Bench. Map, if according to the method you provided, the map will be updated every time “Map” is pressed, which may not be what I want. But this puts me in a situation where if I restart the game, I cannot update the map to the current progress before interacting with Bench.

    SaveData.cs

    <code>
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    
    [System.Serializable]
    
    public struct SaveData
    {
        public static SaveData Instance;
    
        //map stuff
        public HashSet<string> sceneName;
    
        public HashSet<string> mapName;
    
        //savePoint stuff
        public string savePointSceneName;
        public Vector2 savePointPos;
    
        //player stuff
        public float playerHealth;
        public float playerMana;
        public Vector2 playerPosition;
        public string lastScene;
    
        //player skill
        public bool playerUnlockWallJump;
        public bool playerUnlockDash;
        public bool playeUnlockAirJump;
        public bool playerUnlockSideSpell;
    
        public void Initialize() //初始化
        {
            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
    
            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.savePoint.data"));
            }
    
            //檢查玩家文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
            }
    
            if (sceneName == null) //檢查此場景是否為空 
            {
                //如果是,建立一個新HashSet
                sceneName = new HashSet<string>();
            }
    
            if (mapName == null) //檢查此場景是否為空 
            {
                //如果是,建立一個新HashSet
                mapName = new HashSet<string>();
            }
    
        }
    
        public void SavedSavePoint()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.savePoint.data")))
            {
                Debug.Log("SavedSavePoint by SaveData.cs");
                writer.Write(savePointSceneName);
                writer.Write(savePointPos.x);
                writer.Write(savePointPos.y);
            }
        }
    
        public void LoadSavePoint()
        {
            //if(File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            string savePath = Application.persistentDataPath + "/save.savePoint.data";
            if(File.Exists(savePath) && new FileInfo(savePath).Length > 0)
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.savePoint.data")))
                {
                    Debug.Log("LoadSavePoint by SaveData.cs");
                    savePointSceneName = reader.ReadString();
                    savePointPos.x = reader.ReadSingle();
                    savePointPos.y = reader.ReadSingle();
                }
            }
            else
            {
                Debug.Log("SavePoint do not exits by SaveData.cs");
            }
        }
    
        public void SavePlayerData() //備註:存儲的順序需與讀取的順序相同,否則可能出錯
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
            {
                //血量、魔力
                playerHealth = PlayerController.Instance.Health;
                writer.Write(playerHealth);
                playerMana = PlayerController.Instance.Mana;
                writer.Write(playerMana);
                //技能
                playerUnlockWallJump = PlayerController.Instance.unlockWallJump;
                writer.Write(playerUnlockWallJump);
                playerUnlockDash = PlayerController.Instance.unlockDash;
                writer.Write(playerUnlockDash);
                playeUnlockAirJump = PlayerController.Instance.unlockAirJump;
                writer.Write(playeUnlockAirJump);
    
                playerUnlockSideSpell = PlayerController.Instance.unlockSideSpell;
                writer.Write(playerUnlockSideSpell);
    
                //位置
                playerPosition = PlayerController.Instance.transform.position;
                writer.Write(playerPosition.x);
                writer.Write(playerPosition.y);
                //場景
                lastScene = SceneManager.GetActiveScene().name;
                writer.Write(lastScene);
            }
        }
    
        public void LoadPlayerData()
        {
            //string savePath = Application.persistentDataPath + "/save.player.data";
            //if (File.Exists(savePath) && new FileInfo(savePath).Length > 0) 
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    //血量、魔力
                    playerHealth = reader.ReadSingle();
                    playerMana = reader.ReadSingle();
                    //技能
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerUnlockDash = reader.ReadBoolean();
                    playeUnlockAirJump = reader.ReadBoolean();
    
                    playerUnlockSideSpell = reader.ReadBoolean();
    
                    //位置
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    //場景
                    lastScene = reader.ReadString();
                    Debug.Log(lastScene + "LoadPlayerData by SaveData.cs");
    
                    SceneManager.LoadScene(lastScene);
                    PlayerController.Instance.transform.position = playerPosition;
                    PlayerController.Instance.Health = playerHealth;
                    PlayerController.Instance.Mana = playerMana;
    
                    PlayerController.Instance.unlockWallJump = playerUnlockWallJump;
                    PlayerController.Instance.unlockDash = playerUnlockDash;
                    PlayerController.Instance.unlockAirJump = playeUnlockAirJump;
    
                    PlayerController.Instance.unlockSideSpell = playerUnlockSideSpell;
                }
                Debug.Log("load player data");
            }
            else
            {
                //如果檔案不存在
                Debug.Log("File doesnt exist");
                PlayerController.Instance.Health = PlayerController.Instance.maxHealth;
                PlayerController.Instance.Mana = 0.5f;
                PlayerController.Instance.unlockWallJump = false;
                PlayerController.Instance.unlockDash = false;
                PlayerController.Instance.unlockAirJump = false;
                PlayerController.Instance.unlockSideSpell = false;
    
            }
        }
    
    
    
        public void SaveSceneData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.scenes.data")))
            {
                Debug.Log("SaveScene bySavedata.cs");
                writer.Write(sceneName.Count);
                foreach (string sceneName in sceneName)
                {
                    writer.Write(sceneName);
                }
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    int sceneCount = reader.ReadInt32();
                    //sceneName = new HashSet<string>();
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneName.Add(_sceneName);
                    }
                }
            }
            else
            {
                sceneName = new HashSet<string>();
            }
        }
    
        public void SaveMapData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.maps.data")))
            {
                Debug.Log("Savemaps bySavedata.cs");
    
                mapName = sceneName;
    
                writer.Write(mapName.Count);
                foreach (string mapName in mapName)
                {
                    writer.Write(mapName);
                }
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    int mapCount = reader.ReadInt32();
                    for (int i = 0; i < mapCount; i++)
                    {
                        string _mapName = reader.ReadString();
                        mapName.Add(_mapName);
    
                        Debug.Log(_mapName);
                    }
                }
            }
            else
            {
                mapName = new HashSet<string>();
            }
        }
    
    }
    </code>
    #15540
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Actually, i believe it’s the opposite. I am actually making it such that your map only updates after interacting with Bench.

    The reason as to how my method above works is through these steps:

    1. The MapManager calls to UpdateMap().
    2. UpdateMap() will only work when mapName in SaveData.cs has any value.
    3. mapName will only ever be updated after SaveMapData() is called through the Bench/SavePoint.cs

    Thus, ONLY whenever you interact with a bench, you update mapName which thereby updates the maps itself. And with the update method being outside of checking for bench interaction, it means that if you continue a game after exiting, it will still update to the last time you saved progress.

    So long as SaveMapData() is not called anywhere else but the bench before.


    Apart from that, you should change your Initialize() method as I believe that’s part of the reason for the issues you may face with deleting the files. Or it’s worth a shot in any case:

            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
    
            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
    
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data"));
            }
    
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
    #15541
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    I think I may have encountered too many problems. For the problems that still exist after I made the above changes, I recorded a video to demonstrate the problems I encountered.

    1. After I interact with any Bench, I can directly update the map as long as I enter the map without interacting with the Bench of the map.
    2. After creating a new game, it will be normal to open the map at the beginning, but after interacting with Bench, the last data will be restored.
    3. After I created a new game, I could not call the pause menu again. Although I could not see my keyboard, at the end of the video, I tried to press the ECS key, but it would not respond.

    MapManager.cs

    <code>private void OnEnable()
        {
            savePoint = FindObjectOfType<SavePoint>();
    
            SaveData.Instance.LoadMapData();
    
            UpdateMap();
        }</code>
    #15546
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Okay, I’m going to need you to send me the following scripts:

    MapManager.cs

    SaveData.cs

    GameManager.cs

    SavePoint.cs

    Afterwards, i’ll take a look at your code and get back to you on what went wrong.

    #15549
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    MapManager.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class MapManager : MonoBehaviour
    {
        [SerializeField] GameObject[] maps;
    
        SavePoint savePoint;
    
        private void OnEnable()
        {
            savePoint = FindObjectOfType<SavePoint>();
    
            SaveData.Instance.LoadMapData();
    
            UpdateMap();
            /*
            if (savePoint != null)
            {
                if(savePoint.interacted)
                {
    
                }
            }
            */
        }
    
        void UpdateMap()
        {
            //var savedScenes = SaveData.Instance.sceneName;
            var savedScenes = SaveData.Instance.mapName;
    
            for (int i = 0; i < maps.Length ; i++)
            {
                if(savedScenes.Contains("Stage_" + (i + 1))) //此處為地圖名稱
                {
                    maps[i].SetActive(true);
                    Debug.Log(savedScenes.Contains("Stage_" + (i + 1)));
                }
                else
                {
                    maps[i].SetActive(false);
                    Debug.Log(savedScenes.Contains("Stage_" + (i + 1)));
                }
            }
        }
    }
    </code>

    SaveData.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    
    [System.Serializable]
    
    public struct SaveData
    {
        public static SaveData Instance;
    
        //map stuff
        public HashSet<string> sceneName;
    
        public HashSet<string> mapName;
    
        //savePoint stuff
        public string savePointSceneName;
        public Vector2 savePointPos;
    
        //player stuff
        public float playerHealth;
        public float playerMana;
        public Vector2 playerPosition;
        public string lastScene;
    
        //player skill
        public bool playerUnlockWallJump;
        public bool playerUnlockDash;
        public bool playeUnlockAirJump;
        public bool playerUnlockSideSpell;
    
        public void Initialize() //初始化
        {
            /*
            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
    
            //檢查場景文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data")))
                {
                    writer.Write(0); // Write an empty scene data structure
                }
            }
            */
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data"));
            }
    
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.savePoint.data"));
            }
    
            //檢查玩家文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
            }
    
            if (sceneName == null) //檢查此場景是否為空 
            {
                //如果是,建立一個新HashSet
                sceneName = new HashSet<string>();
            }
    
            if (mapName == null) //檢查此場景是否為空 
            {
                //如果是,建立一個新HashSet
                mapName = new HashSet<string>();
            }
    
        }
    
        public void SavedSavePoint()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.savePoint.data")))
            {
                Debug.Log("SavedSavePoint by SaveData.cs");
                writer.Write(savePointSceneName);
                writer.Write(savePointPos.x);
                writer.Write(savePointPos.y);
            }
        }
    
        public void LoadSavePoint()
        {
            //if(File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            string savePath = Application.persistentDataPath + "/save.savePoint.data";
            if(File.Exists(savePath) && new FileInfo(savePath).Length > 0)
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.savePoint.data")))
                {
                    Debug.Log("LoadSavePoint by SaveData.cs");
                    savePointSceneName = reader.ReadString();
                    savePointPos.x = reader.ReadSingle();
                    savePointPos.y = reader.ReadSingle();
                }
            }
            else
            {
                Debug.Log("SavePoint do not exits by SaveData.cs");
            }
        }
    
        public void SavePlayerData() //備註:存儲的順序需與讀取的順序相同,否則可能出錯
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
            {
                //血量、魔力
                playerHealth = PlayerController.Instance.Health;
                writer.Write(playerHealth);
                playerMana = PlayerController.Instance.Mana;
                writer.Write(playerMana);
                //技能
                playerUnlockWallJump = PlayerController.Instance.unlockWallJump;
                writer.Write(playerUnlockWallJump);
                playerUnlockDash = PlayerController.Instance.unlockDash;
                writer.Write(playerUnlockDash);
                playeUnlockAirJump = PlayerController.Instance.unlockAirJump;
                writer.Write(playeUnlockAirJump);
    
                playerUnlockSideSpell = PlayerController.Instance.unlockSideSpell;
                writer.Write(playerUnlockSideSpell);
    
                //位置
                playerPosition = PlayerController.Instance.transform.position;
                writer.Write(playerPosition.x);
                writer.Write(playerPosition.y);
                //場景
                lastScene = SceneManager.GetActiveScene().name;
                writer.Write(lastScene);
            }
        }
    
        public void LoadPlayerData()
        {
            //string savePath = Application.persistentDataPath + "/save.player.data";
            //if (File.Exists(savePath) && new FileInfo(savePath).Length > 0) 
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    //血量、魔力
                    playerHealth = reader.ReadSingle();
                    playerMana = reader.ReadSingle();
                    //技能
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerUnlockDash = reader.ReadBoolean();
                    playeUnlockAirJump = reader.ReadBoolean();
    
                    playerUnlockSideSpell = reader.ReadBoolean();
    
                    //位置
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    //場景
                    lastScene = reader.ReadString();
                    Debug.Log(lastScene + "LoadPlayerData by SaveData.cs");
    
                    SceneManager.LoadScene(lastScene);
                    PlayerController.Instance.transform.position = playerPosition;
                    PlayerController.Instance.Health = playerHealth;
                    PlayerController.Instance.Mana = playerMana;
    
                    PlayerController.Instance.unlockWallJump = playerUnlockWallJump;
                    PlayerController.Instance.unlockDash = playerUnlockDash;
                    PlayerController.Instance.unlockAirJump = playeUnlockAirJump;
    
                    PlayerController.Instance.unlockSideSpell = playerUnlockSideSpell;
                }
                Debug.Log("load player data");
            }
            else
            {
                //如果檔案不存在
                Debug.Log("File doesnt exist");
                PlayerController.Instance.Health = PlayerController.Instance.maxHealth;
                PlayerController.Instance.Mana = 0.5f;
                PlayerController.Instance.unlockWallJump = false;
                PlayerController.Instance.unlockDash = false;
                PlayerController.Instance.unlockAirJump = false;
                PlayerController.Instance.unlockSideSpell = false;
    
            }
        }
    
    
    
        public void SaveSceneData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.scenes.data")))
            {
                Debug.Log("SaveScene bySavedata.cs");
                writer.Write(sceneName.Count);
                foreach (string sceneName in sceneName)
                {
                    writer.Write(sceneName);
                }
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    int sceneCount = reader.ReadInt32();
                    //sceneName = new HashSet<string>();
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneName.Add(_sceneName);
                    }
                }
            }
            else
            {
                sceneName = new HashSet<string>();
            }
        }
    
        public void SaveMapData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.maps.data")))
            {
                Debug.Log("Savemaps bySavedata.cs");
    
                mapName = sceneName;
    
                writer.Write(mapName.Count);
                foreach (string mapName in mapName)
                {
                    writer.Write(mapName);
                }
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    int mapCount = reader.ReadInt32();
                    for (int i = 0; i < mapCount; i++)
                    {
                        string _mapName = reader.ReadString();
                        mapName.Add(_mapName);
    
                        Debug.Log(_mapName);
                    }
                }
            }
            else
            {
                mapName = new HashSet<string>();
            }
        }
    
    }
    </code>

    GameManager.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class GameManager : MonoBehaviour
    {
        public string transitionedFromScene;  //儲存前一個場景
    
        public Vector2 platformingRespawnPoint; //重生點
        public Vector2 respawnPoint;
        [SerializeField] SavePoint savePoint;
    
        [SerializeField] private FadeUI pauseMenu;
        [SerializeField] private float fadeTime;
        public bool gameIsPaused;
        //public bool Resumed = false;
    
        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            SaveData.Instance.Initialize();
    
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
    
            SaveScene();
    
            DontDestroyOnLoad(gameObject);
    
            SaveData.Instance.LoadSceneData();
    
            SaveData.Instance.LoadMapData();
    
            savePoint = FindObjectOfType<SavePoint>();
        }
    
        private void Update()
        {
            if(Input.GetKeyDown(KeyCode.P)) //test
            {
                Debug.Log("P");
                SaveData.Instance.SavePlayerData();
            }
    
            if(Input.GetKeyDown(KeyCode.Escape) && !gameIsPaused)
            {
                pauseMenu.FadeUIIn(fadeTime);
                Time.timeScale = 0;
                GameManager.Instance.gameIsPaused = true;
            }
    
            if(Input.GetKeyDown(KeyCode.R)) //test
            {
                //SaveData.Instance.DeleteAllSaveData();
            }
        }
        public void SaveGame()
        {
            SaveData.Instance.SavePlayerData();
        }
    
        public void UnpauseGame()
        {
            //Resumed = true;
            Time.timeScale = 1;
            GameManager.Instance.gameIsPaused = false; //沒有正確銷毀gamemanager 導致需要加GameManager.Instance
            Debug.Log(gameIsPaused);
        }
    
        public void SaveScene()
        {
            //獲取當前場景名稱
            string currentSceneName = SceneManager.GetActiveScene().name;
            SaveData.Instance.sceneName.Add(currentSceneName);
            SaveData.Instance.SaveSceneData();
    
            //Debug.Log("saved" + currentSceneName);
    
        }
    
        public void RespawnPlayer()
        {
            SaveData.Instance.LoadSavePoint();
    
            if(SaveData.Instance.savePointSceneName != null) //載入重生點的場景
            {
                print(SaveData.Instance.savePointSceneName + "by GameManager");
                SceneManager.LoadScene(SaveData.Instance.savePointSceneName);
            }
    
            if(SaveData.Instance.savePointPos != null) //設定重生位置為savePoint
            {
                respawnPoint = SaveData.Instance.savePointPos;
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint;
    
            StartCoroutine(UIManager.Instance.DeactiveateDeathScreen()); //重生點淡入淡出
            PlayerController.Instance.Respawned(); //使角色重生
        }
    }
    </code>

    SavePoint.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class SavePoint : MonoBehaviour
    {
        public bool interacted;
        bool inRange = false;
    
        void Update()
        {
            if(Input.GetButtonDown("Interact") && inRange )
            {
                interacted = true;
    
                SaveData.Instance.savePointSceneName = SceneManager.GetActiveScene().name;
                SaveData.Instance.savePointPos = new Vector2(gameObject.transform.position.x, gameObject.transform.position.y);
    
                GameManager.Instance.platformingRespawnPoint = SaveData.Instance.savePointPos;
    
                SaveData.Instance.SavedSavePoint();
                SaveData.Instance.SavePlayerData();
                SaveData.Instance.SaveMapData();
                //SaveData.Instance.SaveSceneData();
    
                Debug.Log("Save by SavePoint.cs");
            }
        }
    
        private void OnTriggerEnter2D(Collider2D _collision)
        {
            if (_collision.CompareTag("Player")) inRange = true;
        }
    
        private void OnTriggerExit2D(Collider2D _collision)
        {
            if (_collision.CompareTag("Player"))
            {
                //interacted = false;
                inRange = false;
            }
        }
    }
    </code>
    #15579
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Hi there I would like to ask if there is a solution to the problem, it has been bothering me for several days but I don’t know how to solve it. I don’t know how to ask you more politely. Please forgive me if I offend you.

    #15580
    Joseph Tang
    Level 12
    Participant
    Helpful?
    Up
    0
    ::

    Apologies for the wait, I have been busy in the meantime.

    Would it be alright if i get back to you, sometime within today and tomorrow, with a theory/solution after attempting to work out a solution.

    #15581
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Of course, I’m not urging you, I’m just curious if there is a solution. I’m grateful for your help.

    #15588
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    After going through the code yet again. I’ve come to a conclusion.

    The save system for scenes and maps simply does not actually work. The code used to “save” data, is not actually being saved through the method we are using. We’ll have to come up with a functional save system for hashsets since the one we use now only saves 1 value of sceneName instead of actually saving the hashset.

    #15589
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    I want to know if you have a chance to propose a solution later. I learned most of the programs from you, especially the storage method. This is a type that I have never been exposed to until now. I know nothing about it. , I think I need your help

    #15596
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    MI NI, we can make a video about this, but it will take awhile. Will you be able to wait?

    #15597
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Of course, thank you for your teaching. It is of great help to me in learning programming.

    #15771
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Hi MI NI,

    It’s been a while but first, apologies for not revisiting this sooner. Second, I’ve finally, most probably found the actual issue for why the maps did not work.

    After revisiting the code again, I’ve determined that the original code does actually work. So let’s just revert the code to this: In SaveData.cs, we will use the original code where we save both the Maps and the Scenes seperately as hashset strings. The code here actually does work and is saved in their respective paths.

    We will not be calling the SceneData() or MapData() from this. So do remove any mentions of it from Initialize().

    SaveData.cs

        public void Initialize()
        {
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data")) //if file doesnt exist, well create the file
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
    
            if (sceneNames == null)
            {
                sceneNames = new HashSet<string>();
            }
    
            if (mapNames == null)
            {
                mapNames = new HashSet<string>();
            }
        }
    
        public void SaveScene()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.scenes.data")))
            {
                writer.Write(sceneNames.Count);
                foreach (string sceneName in sceneNames)
                {
                    writer.Write(sceneName);
                }
    
                writer.Flush();
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                Debug.Log(sceneNames);
                sceneNames = new HashSet<string>();
            }
        }
    
        public void SaveMapData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.maps.data")))
            {
    
                mapNames = sceneNames;
                writer.Write(mapNames.Count);
                foreach (string mapName in mapNames)
                {
                    writer.Write(mapName);
                }
    
                writer.Flush();
            }
        }
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        mapNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                mapNames = new HashSet<string>();
            }
        }

    The real issue is in the GameManager.cs.

    The GameManager.cs calls SaveScene() BEFORE it calls LoadSceneData(). Once realizing this, it becomes obvious that this is counter productive.

    The reason why this is bad is because, everytime you enter a new scene, we will add the scene in the sceneNames hashset. That is intented. However, when we call LoadSceneData() we are taking all the sceneNames that were saved through SaveScene(). Because we call SaveScene() before LoadSceneData() we are never really adding any new scenes and are actually replacing old saved data instead.

    In other words, we are basically resetting our progress through this. So all we have to do is reorder the code:

    GameManager.cs

        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            SaveData.Instance.Initialize();
    
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
    
            SaveScene();
    
            DontDestroyOnLoad(gameObject);
    
            SaveData.Instance.LoadSceneData();
    
            SaveScene();
    
            SaveData.Instance.LoadMapData();
    
            savePoint = FindObjectOfType<SavePoint>();
        }
    #15793
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Hello, I have successfully tested it and it works, but I am facing some problems so that I cannot test and open the map after starting the game. I’ll describe my problem here and I can republish an article if needed.

    The problems I’m currently having are: first question Pressing ESC immediately when switching scenes will cause the game to freeze permanently. second question When I create a new game, ESC, inventory, and maps don’t work

    #15794
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Could you send your PlayerController.cs and your GameManager.cs? and maybe your SaveData.cs.

    #15795
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    sure In addition, I think this problem existed before, not when the storage function was modified this time. savedata.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    
    [System.Serializable]
    
    public struct SaveData
    {
        public static SaveData Instance;
    
        //map stuff
        public HashSet<string> sceneNames;
    
        public HashSet<string> mapNames;
    
        //savePoint stuff
        public string savePointSceneName;
        public Vector2 savePointPos;
    
        //player stuff
        public float playerHealth;
        public float playerMana;
        public Vector2 playerPosition;
        public string lastScene;
    
        //player skill
        public bool playerUnlockWallJump;
        public bool playerUnlockDash;
        public bool playeUnlockAirJump;
        public bool playerUnlockSideSpell;
    
        public void Initialize() //初始化
        {
            /*
            if (!File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.scenes.data"));
            }
    
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
            */
    
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data")) //if file doesnt exist, well create the file
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
    
            if (sceneNames == null)
            {
                sceneNames = new HashSet<string>();
            }
    
            if (mapNames == null)
            {
                mapNames = new HashSet<string>();
            }
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.savePoint.data"));
            }
    
            //檢查玩家文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
            }
    
        }
    
        public void SavedSavePoint()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.savePoint.data")))
            {
                Debug.Log("SavedSavePoint by SaveData.cs");
                writer.Write(savePointSceneName);
                writer.Write(savePointPos.x);
                writer.Write(savePointPos.y);
            }
        }
    
        public void LoadSavePoint()
        {
            //if(File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            string savePath = Application.persistentDataPath + "/save.savePoint.data";
            if(File.Exists(savePath) && new FileInfo(savePath).Length > 0)
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.savePoint.data")))
                {
                    Debug.Log("LoadSavePoint by SaveData.cs");
                    savePointSceneName = reader.ReadString();
                    savePointPos.x = reader.ReadSingle();
                    savePointPos.y = reader.ReadSingle();
                }
            }
            else
            {
                Debug.Log("SavePoint do not exits by SaveData.cs");
            }
        }
    
        public void SavePlayerData() //備註:存儲的順序需與讀取的順序相同,否則可能出錯
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
            {
                //血量、魔力
                playerHealth = PlayerController.Instance.Health;
                writer.Write(playerHealth);
                playerMana = PlayerController.Instance.Mana;
                writer.Write(playerMana);
                //技能
                playerUnlockWallJump = PlayerController.Instance.unlockWallJump;
                writer.Write(playerUnlockWallJump);
                playerUnlockDash = PlayerController.Instance.unlockDash;
                writer.Write(playerUnlockDash);
                playeUnlockAirJump = PlayerController.Instance.unlockAirJump;
                writer.Write(playeUnlockAirJump);
    
                playerUnlockSideSpell = PlayerController.Instance.unlockSideSpell;
                writer.Write(playerUnlockSideSpell);
    
                //位置
                playerPosition = PlayerController.Instance.transform.position;
                writer.Write(playerPosition.x);
                writer.Write(playerPosition.y);
                //場景
                lastScene = SceneManager.GetActiveScene().name;
                writer.Write(lastScene);
            }
        }
    
        public void LoadPlayerData()
        {
            //string savePath = Application.persistentDataPath + "/save.player.data";
            //if (File.Exists(savePath) && new FileInfo(savePath).Length > 0) 
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    //血量、魔力
                    playerHealth = reader.ReadSingle();
                    playerMana = reader.ReadSingle();
                    //技能
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerUnlockDash = reader.ReadBoolean();
                    playeUnlockAirJump = reader.ReadBoolean();
    
                    playerUnlockSideSpell = reader.ReadBoolean();
    
                    //位置
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    //場景
                    lastScene = reader.ReadString();
                    Debug.Log(lastScene + "LoadPlayerData by SaveData.cs");
    
                    SceneManager.LoadScene(lastScene);
                    PlayerController.Instance.transform.position = playerPosition;
                    PlayerController.Instance.Health = playerHealth;
                    PlayerController.Instance.Mana = playerMana;
    
                    PlayerController.Instance.unlockWallJump = playerUnlockWallJump;
                    PlayerController.Instance.unlockDash = playerUnlockDash;
                    PlayerController.Instance.unlockAirJump = playeUnlockAirJump;
    
                    PlayerController.Instance.unlockSideSpell = playerUnlockSideSpell;
                }
                Debug.Log("load player data");
            }
            else
            {
                //如果檔案不存在
                Debug.Log("File doesnt exist");
                PlayerController.Instance.Health = PlayerController.Instance.maxHealth;
                PlayerController.Instance.Mana = 0.5f;
                PlayerController.Instance.unlockWallJump = false;
                PlayerController.Instance.unlockDash = false;
                PlayerController.Instance.unlockAirJump = false;
                PlayerController.Instance.unlockSideSpell = false;
    
            }
        }
    
    
    
        public void SaveSceneData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.scenes.data")))
            {
                writer.Write(sceneNames.Count);
                foreach (string sceneName in sceneNames)
                {
                    writer.Write(sceneName);
                }
    
                writer.Flush();
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                Debug.Log(sceneNames);
                sceneNames = new HashSet<string>();
            }
        }
    
        public void SaveMapData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.maps.data")))
            {
    
                mapNames = sceneNames;
                writer.Write(mapNames.Count);
                foreach (string mapName in mapNames)
                {
                    writer.Write(mapName);
                }
    
                writer.Flush();
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        mapNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                mapNames = new HashSet<string>();
            }
        }
    
    }

    GameManager.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class GameManager : MonoBehaviour
    {
        public string transitionedFromScene;  //儲存前一個場景
    
        public Vector2 platformingRespawnPoint; //重生點
        public Vector2 respawnPoint;
        [SerializeField] SavePoint savePoint;
    
        [SerializeField] private FadeUI pauseMenu;
        [SerializeField] private FadeUI mapPause;
        [SerializeField] private float fadeTime;
        public bool gameIsPaused;
        //public bool Resumed = false;
    
        bool openMap = false;
        bool openInventory = false;
    
        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            SaveData.Instance.Initialize();
    
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
    
    
    
            DontDestroyOnLoad(gameObject);
    
            SaveData.Instance.LoadSceneData();
    
            SaveScene();
    
            SaveData.Instance.LoadMapData();
    
            savePoint = FindObjectOfType<SavePoint>();
    
        }
    
        private void Update()
        {
            //退出
            if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPaused)
            {
                pauseMenu.FadeUIIn(fadeTime);
                Time.timeScale = 0;
                GameManager.Instance.gameIsPaused = true;
            }
    
            //地圖
            if (Input.GetButtonDown("Map") && !openMap && !gameIsPaused)
            {
                openMap = true;
    
                if (openMap)
                {
                    Time.timeScale = 0;
                    GameManager.Instance.gameIsPaused = true;
                }
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else if (Input.GetButtonDown("Map") && openMap)
            {
                openMap = false;
    
                if (!openMap)
                {
                    UnpauseGame();
                }
                UIManager.Instance.mapHandler.SetActive(false);
            }
    
            //背包
            if (Input.GetButtonDown("Inventory") && !openInventory && !gameIsPaused)
            {
                openInventory = true;
    
                if(openInventory)
                {
                    Time.timeScale = 0;
                    GameManager.Instance.gameIsPaused = true;
                }
                UIManager.Instance.inventory.SetActive(true);
            }
            else if (Input.GetButtonDown("Inventory") && openInventory)
            {
                openInventory = false;
    
                if(!openInventory)
                {
                    UnpauseGame();
                }
                UIManager.Instance.inventory.SetActive(false) ;
            }
        }
    
        public void SaveGame()
        {
            SaveData.Instance.SavePlayerData();
        }
    
        public void UnpauseGame()
        {
            //Resumed = true;
            Time.timeScale = 1;
            GameManager.Instance.gameIsPaused = false; //沒有正確銷毀gamemanager 導致需要加GameManager.Instance
            Debug.Log(gameIsPaused);
        }
    
        public void SaveScene()
        {
            //獲取當前場景名稱
            string currentSceneName = SceneManager.GetActiveScene().name;
            SaveData.Instance.sceneNames.Add(currentSceneName);
            SaveData.Instance.SaveSceneData();
    
            //Debug.Log("saved" + currentSceneName);
        }
    
        public void RespawnPlayer()
        {
            SaveData.Instance.LoadSavePoint();
    
            if(SaveData.Instance.savePointSceneName != null) //載入重生點的場景
            {
                print(SaveData.Instance.savePointSceneName + "by GameManager");
                SceneManager.LoadScene(SaveData.Instance.savePointSceneName);
            }
    
            if(SaveData.Instance.savePointPos != null) //設定重生位置為savePoint
            {
                respawnPoint = SaveData.Instance.savePointPos;
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint;
    
            StartCoroutine(UIManager.Instance.DeactiveateDeathScreen()); //重生點淡入淡出
            PlayerController.Instance.Respawned(); //使角色重生
        }
    
        /*
        public void ToggleMap()
        {
            if (openMap)
            {
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
        */
    }
    </code>
    #15808
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    1
    ::
    1. For your Pause menu freezing the game, the only thing you need to do is to ensure your resume game is called. In other words, making sure you can press the resume button.

    Thus, let’s first see why your button isn’t able to be pressed. For this, I’m not too sure, however can you check out point 2b. of this article, turning off the raycast targetting of the “Scene Fader”:

    How to fix an unclickable Button in Unity’s Canvas UI system

    This is because it’s the only game object in the scene that could possibly be blocking the pause menu.

    Furthermore, I suggest you allow pressing the escape button again to unpause the game anyways.


    1. For your Pause, Map and Inventory not appearing. This is because you put all three into the GameManager.cs. The problem with that is due to the fact that the code we used for loading the game’s map, scenes and boss data is all not fully correct.

    Whenever we load the game’s data, we search for whether their file paths exists. but we forgot to check if there’s anything inside the file. Because of this, we will always be returned with an error saying that there was no data to be retrieved from the filepaths. Whenever your code encounters an error, the script will be paused there. Thus, since we called a lot of Load Data methods in the GameManager.cs Awake() method, our GameManager.cs encountered errors when we reset the game’s data and stopped functioning for the Update() method to fire. Thereby causing your map, inventory and pause menu unable to open.

    The fix is pretty simple, we just need to add the line that was commented out in your LoadPlayerData(), into each of the Load methods:

    GameManager.cs

    
        public void LoadPlayerData()
        {
            //string savePath = Application.persistentDataPath + "/save.player.data";
            //if (File.Exists(savePath) && new FileInfo(savePath).Length > 0) 
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    ....
                }
                Debug.Log("load player data");
            }
            else
            {
             ....
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data") && new FileInfo(Application.persistentDataPath + "/save.scenes.data").Length > 0))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    ...
                }
            }
            else
            {
                Debug.Log(sceneNames);
                Debug.Log("File doesnt exist");
                sceneNames = new HashSet();
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data") && new FileInfo(Application.persistentDataPath + "/save.maps.data").Length > 0))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    ...
                }
            }
            else
            {
                Debug.Log("File doesnt exist");
                mapNames = new HashSet();
            }
        }

    What this does is it checks for the contents of each file path first and sees if there is anything inside. If there is nothing inside, then we fire the else statement that the file doesnt exist. The reason we have to do this is because of our SaveData.cs Initialize() creating the file paths even if we deleted them with the reset data.

    has upvoted this post.
    #15814
    MI NI
    Level 16
    Former Patron
    Helpful?
    Up
    0
    ::

    Hello, I’m sorry for the late reply. After I started Unity today and made some modifications, I still can’t use ESC, map and inventory when starting a new game. In addition, after I set ESC to be the same button to switch the pause interface on and off, the freezing problem seems to be there. Got resolved (this needs to be confirmed as I have bigger issues). The bigger problem is that my pause interface and inventory are no longer usable. I haven’t made any modifications during this period, but suddenly all the buttons are invalid. I refer to your article on how to fix unclickable Button. , but it seems to have no effect

    After testing, I found that the UI Button cannot be triggered on the first map, but it can be triggered on the second map. I will add a test video below. This makes me confused. If you need any information or other, please must tell me

    Gamemanager.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class GameManager : MonoBehaviour
    {
        public string transitionedFromScene;  //儲存前一個場景
    
        public Vector2 platformingRespawnPoint; //重生點
        public Vector2 respawnPoint;
        [SerializeField] SavePoint savePoint;
    
        [SerializeField] private FadeUI pauseMenu;
        [SerializeField] private FadeUI mapPause;
        [SerializeField] private float fadeTime;
        public bool gameIsPaused;
        //public bool Resumed = false;
    
        bool openMap = false;
        bool openInventory = false;
    
        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            SaveData.Instance.Initialize();
    
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
    
    
    
            DontDestroyOnLoad(gameObject);
    
            SaveData.Instance.LoadSceneData();
    
            SaveScene();
    
            SaveData.Instance.LoadMapData();
    
            savePoint = FindObjectOfType<SavePoint>();
    
        }
    
        private void Update()
        {
            //退出
            if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPaused)
            {
                pauseMenu.FadeUIIn(fadeTime);
                Time.timeScale = 0;
                GameManager.Instance.gameIsPaused = true;
            }
            else if(Input.GetKeyDown(KeyCode.Escape) && gameIsPaused)
            {
                UnpauseGame();
                pauseMenu.FadeUIOut(fadeTime);
            }
    
    
            //地圖
            if (Input.GetButtonDown("Map") && !openMap && !gameIsPaused)
            {
                openMap = true;
    
                if (openMap)
                {
                    Time.timeScale = 0;
                    GameManager.Instance.gameIsPaused = true;
                }
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else if (Input.GetButtonDown("Map") && openMap)
            {
                openMap = false;
    
                if (!openMap)
                {
                    UnpauseGame();
                }
                UIManager.Instance.mapHandler.SetActive(false);
            }
    
            //背包
            if (Input.GetButtonDown("Inventory") && !openInventory && !gameIsPaused)
            {
                openInventory = true;
    
                if(openInventory)
                {
                    Time.timeScale = 0;
                    GameManager.Instance.gameIsPaused = true;
                }
                UIManager.Instance.inventory.SetActive(true);
            }
            else if (Input.GetButtonDown("Inventory") && openInventory)
            {
                openInventory = false;
    
                if(!openInventory)
                {
                    UnpauseGame();
                }
                UIManager.Instance.inventory.SetActive(false) ;
            }
        }
    
        public void SaveGame()
        {
            SaveData.Instance.SavePlayerData();
        }
    
        public void UnpauseGame()
        {
            //Resumed = true;
            Time.timeScale = 1;
            GameManager.Instance.gameIsPaused = false; //沒有正確銷毀gamemanager 導致需要加GameManager.Instance
            Debug.Log(gameIsPaused);
        }
    
        public void SaveScene()
        {
            //獲取當前場景名稱
            string currentSceneName = SceneManager.GetActiveScene().name;
            SaveData.Instance.sceneNames.Add(currentSceneName);
            SaveData.Instance.SaveSceneData();
    
            //Debug.Log("saved" + currentSceneName);
        }
    
        public void RespawnPlayer()
        {
            SaveData.Instance.LoadSavePoint();
    
            if(SaveData.Instance.savePointSceneName != null) //載入重生點的場景
            {
                print(SaveData.Instance.savePointSceneName + "by GameManager");
                SceneManager.LoadScene(SaveData.Instance.savePointSceneName);
            }
    
            if(SaveData.Instance.savePointPos != null) //設定重生位置為savePoint
            {
                respawnPoint = SaveData.Instance.savePointPos;
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint;
    
            StartCoroutine(UIManager.Instance.DeactiveateDeathScreen()); //重生點淡入淡出
            PlayerController.Instance.Respawned(); //使角色重生
        }
    
        /*
        public void ToggleMap()
        {
            if (openMap)
            {
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
        */
    }
    </code>

    SavaData.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    
    [System.Serializable]
    
    public struct SaveData
    {
        public static SaveData Instance;
    
        //map stuff
        public HashSet<string> sceneNames;
    
        public HashSet<string> mapNames;
    
        //savePoint stuff
        public string savePointSceneName;
        public Vector2 savePointPos;
    
        //player stuff
        public float playerHealth;
        public float playerMana;
        public Vector2 playerPosition;
        public string lastScene;
    
        //player skill
        public bool playerUnlockWallJump;
        public bool playerUnlockDash;
        public bool playeUnlockAirJump;
        public bool playerUnlockSideSpell;
    
        public void Initialize() //初始化
        {
            if (!File.Exists(Application.persistentDataPath + "/save.maps.data")) //if file doesnt exist, well create the file
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.maps.data"));
            }
    
            if (sceneNames == null)
            {
                sceneNames = new HashSet<string>();
            }
    
            if (mapNames == null)
            {
                mapNames = new HashSet<string>();
            }
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.savePoint.data"));
            }
    
            //檢查玩家文件是否存在,否則將建立一個新文件
            if (!File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
            }
    
        }
    
        public void SavedSavePoint()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.savePoint.data")))
            {
                Debug.Log("SavedSavePoint by SaveData.cs");
                writer.Write(savePointSceneName);
                writer.Write(savePointPos.x);
                writer.Write(savePointPos.y);
            }
        }
    
        public void LoadSavePoint()
        {
            //if(File.Exists(Application.persistentDataPath + "/save.savePoint.data"))
            string savePath = Application.persistentDataPath + "/save.savePoint.data";
            if(File.Exists(savePath) && new FileInfo(savePath).Length > 0)
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.savePoint.data")))
                {
                    Debug.Log("LoadSavePoint by SaveData.cs");
                    savePointSceneName = reader.ReadString();
                    savePointPos.x = reader.ReadSingle();
                    savePointPos.y = reader.ReadSingle();
                }
            }
            else
            {
                Debug.Log("SavePoint do not exits by SaveData.cs");
            }
        }
    
        public void SavePlayerData() //備註:存儲的順序需與讀取的順序相同,否則可能出錯
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
            {
                //血量、魔力
                playerHealth = PlayerController.Instance.Health;
                writer.Write(playerHealth);
                playerMana = PlayerController.Instance.Mana;
                writer.Write(playerMana);
                //技能
                playerUnlockWallJump = PlayerController.Instance.unlockWallJump;
                writer.Write(playerUnlockWallJump);
                playerUnlockDash = PlayerController.Instance.unlockDash;
                writer.Write(playerUnlockDash);
                playeUnlockAirJump = PlayerController.Instance.unlockAirJump;
                writer.Write(playeUnlockAirJump);
    
                playerUnlockSideSpell = PlayerController.Instance.unlockSideSpell;
                writer.Write(playerUnlockSideSpell);
    
                //位置
                playerPosition = PlayerController.Instance.transform.position;
                writer.Write(playerPosition.x);
                writer.Write(playerPosition.y);
                //場景
                lastScene = SceneManager.GetActiveScene().name;
                writer.Write(lastScene);
            }
        }
    
        public void LoadPlayerData()
        {
            string savePath = Application.persistentDataPath + "/save.player.data";
            if (File.Exists(savePath) && new FileInfo(savePath).Length > 0)
            //if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    //血量、魔力
                    playerHealth = reader.ReadSingle();
                    playerMana = reader.ReadSingle();
                    //技能
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerUnlockDash = reader.ReadBoolean();
                    playeUnlockAirJump = reader.ReadBoolean();
    
                    playerUnlockSideSpell = reader.ReadBoolean();
    
                    //位置
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    //場景
                    lastScene = reader.ReadString();
                    Debug.Log(lastScene + "LoadPlayerData by SaveData.cs");
    
                    SceneManager.LoadScene(lastScene);
                    PlayerController.Instance.transform.position = playerPosition;
                    PlayerController.Instance.Health = playerHealth;
                    PlayerController.Instance.Mana = playerMana;
    
                    PlayerController.Instance.unlockWallJump = playerUnlockWallJump;
                    PlayerController.Instance.unlockDash = playerUnlockDash;
                    PlayerController.Instance.unlockAirJump = playeUnlockAirJump;
    
                    PlayerController.Instance.unlockSideSpell = playerUnlockSideSpell;
                }
                Debug.Log("load player data");
            }
            else
            {
                //如果檔案不存在
                Debug.Log("File doesnt exist");
                PlayerController.Instance.Health = PlayerController.Instance.maxHealth;
                PlayerController.Instance.Mana = 0.5f;
                PlayerController.Instance.unlockWallJump = false;
                PlayerController.Instance.unlockDash = false;
                PlayerController.Instance.unlockAirJump = false;
                PlayerController.Instance.unlockSideSpell = false;
    
            }
        }
    
    
    
        public void SaveSceneData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.scenes.data")))
            {
                writer.Write(sceneNames.Count);
                foreach (string sceneName in sceneNames)
                {
                    writer.Write(sceneName);
                }
    
                writer.Flush();
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                Debug.Log("File doesnt exist");
                sceneNames = new HashSet<string>();
            }
        }
    
        public void SaveMapData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.maps.data")))
            {
    
                mapNames = sceneNames;
                writer.Write(mapNames.Count);
                foreach (string mapName in mapNames)
                {
                    writer.Write(mapName);
                }
    
                writer.Flush();
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    int sceneCount = reader.ReadInt32();
    
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        mapNames.Add(_sceneName);
                    }
                }
            }
            else
            {
                Debug.Log("File doesnt exist");
                mapNames = new HashSet<string>();
            }
        }
    
    }
    </code>
    #15815
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Could you try applying the changes [the addition of the file.length check] to SaveData.cs LoadSceneData() and LoadMapData() like in my post above?

        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data") && new FileInfo(Application.persistentDataPath + "/save.scenes.data").Length > 0))
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data") && new FileInfo(Application.persistentDataPath + "/save.maps.data").Length > 0))
Viewing 20 posts - 41 through 60 (of 71 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: