Forum begins after the advertisement:


[Part 7] Map problem

Viewing 15 posts - 1 through 15 (of 71 total)
  • Author
    Posts
  • #15465
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    I found that after my map is saved at the save point, only the new map will be updated, and the old map will not be displayed together.
    What should I do to fix it.


    MapManager.cs

    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>();
            if(savePoint != null)
            {
                if(savePoint.interacted)
                {
                    UpdateMap();
                }
            }
        }
    
        void UpdateMap()
        {
            var savedScenes = SaveData.Instance.sceneName;
    
            for(int i = 0; i < maps.Length ; i++)
            {
                if(savedScenes.Contains("Stage_" + (i + 1))) //此處為地圖名稱
                {
                    maps[i].SetActive(true);
                }
                else
                {
                    maps[i].SetActive(false);
                }
            }
        }
    }
    

    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> sceneName;
    
        //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
                }
            }
            LoadSceneData();
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            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>();
            }
        }
    
        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(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 ResetSavePoint()
        {
            savePointSceneName = null;
            savePointPos = Vector2.zero;
        }
    
        public void ResetPlayerData()
        {
            playerHealth = PlayerController.Instance.maxHealth;
            playerMana = 0;
            lastScene = null;
            playerUnlockWallJump = false;
            playerUnlockDash = false;
            playeUnlockAirJump = false;
            playerUnlockSideSpell = false;
        }
    
        public void ResetSceneData()
        {
            sceneName.Clear();
        }
        
        public void DeleteScenesData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.scenes.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("Scenes data deleted.");
            }
            ResetSceneData();
        }
    
        public void DeletePlayerData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.player.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("Player save data deleted.");
            }
            ResetPlayerData();
        }
    
        public void DeleteSavePointData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.savePoint.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("SavePoint save data deleted.");
            }
            ResetSavePoint();
        }
    
        public void DeleteAllSaveData()
        {
            DeleteScenesData();
            DeleteSavePointData();
            DeletePlayerData();
        }
    
    }
    

    In addition, I want to make the map and backpack to continue opening and pausing the game after pressing the button, and then resume after pressing the button again, or press ESC or create an additional button to exit the current screen, but I am stuck on the first step. , I don’t know how to keep it on.
    I have tried the following, but the screen only keeps flickering or cannot be used.

        void GetInputs() //獲取輸入
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attack = Input.GetButtonDown("Attack");
    
            if (Input.GetButtonDown("Map")|| !openMap)
            {
                openMap = true;
            }
            if(Input.GetButtonDown("Map") || openMap)
            {
                openMap = false;
            }
    
            //openMap = Input.GetButton("Map");
    
            openInventory = Input.GetButton("Inventory");
    
            if (Input.GetButton("Cast/Heal"))
            {
                castOrHealtimer += Time.deltaTime;
            }
        }
    
        void ToggleMap()
        {
            if(openMap)
            {
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
        void GetInputs() //獲取輸入
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attack = Input.GetButtonDown("Attack");
    
            if (Input.GetButtonDown("Map")|| !openMap)
            {
                openMap = true;
            }
            else if(Input.GetButtonDown("Map") || openMap)
            {
                openMap = false;
            }
    
            //openMap = Input.GetButton("Map");
    
            openInventory = Input.GetButton("Inventory");
    
            if (Input.GetButton("Cast/Heal"))
            {
                castOrHealtimer += Time.deltaTime;
            }
        }
    
        void ToggleMap()
        {
            if(openMap)
            {
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
    #15466
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Could you show me your GameManager.cs script & Bench script? Or can you check for any instance through the search tool where you called the ResetSavePoint() method in the SaveData.cs?

    I would believe that,
    1. The scene names aren’t being set properly to the maps,
    2. The ResetSavePoint() is being called before you call SaveScene(), thus resetting map progress.
    3. The maps are being deactivated by code accidentally.


    Apart from that, the mechanic you want to achieve is simple.

    Try checking out this post, in my final response on making the escape key resume the game.

    [General] Issue with jumping, walljumping, bat and some questions

    Then, you can apply the same logic with pressing the map key through the GameManager.cs or Player.cs for their respective functions. As for making your Map toggle-able, try using else if instead of if for the second if statement on pressing the map key and see if it works.

    #15468
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    GameManager.cs

    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);
    
            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);
            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(); //使角色重生
        }
    }
    

    SavePoint.cs (Bench)

    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();
    
                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;
            }
        }
        /*
        private void OnTriggerStay2D(Collider2D _collision) //當玩家對儲存點按F 儲存重生點
        {
            if(_collision.CompareTag("Player") && Input.GetButtonDown("Interact"))
            {
                Debug.Log("儲存重生點");
                interacted = true;
    
                
            }
        }
        */
    
    }
    
    #15469
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    I had the wrong name for the method in SaveData.cs, I had referred to ResetSavePoint() instead of ResetSceneData().

    Anyways, just to be sure, what key is your interact input?
    If it is “R”, then the issue is that your DeleteAllSavedData() is tied to R in GameManager.cs.

    I can’t tell what else it could be since your MapManager.cs will only deactivate your maps if they aren’t present in SaveData.cs sceneName list. Thus, why i believe the delete data is being called and resetting the scene names in the SaveData.cs.

    #15472
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    My interactive input is the F key, and the R key was previously used to test whether there was a way to delete data.

    #15473
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    My interactive input is the F key, and the R key was used previously as a test to see if there was a way to delete the data.

    About ResetSavePoint() and ResetSceneData().
    Do I need to make any changes?

    #15474
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Hm, can you try going from Stage_1 to Stage_2?

    I think our mechanic isn’t able to find stages across different sequences [Stage 1, 3, 2] than increasing order. [Stage 1, 2, 3]

    #15475
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    I tested from Stage_1 to Stage_2, but the result was the same. It would still delete the previous map. When I watched the tutorial video, the test was all about moving from Stage_1 to Stage_3, but it still worked.

    #15476
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    I found a mistake in another question I made before. I mistakenly used || to judge. I should use && to make it work normally.

            if (Input.GetButtonDown("Map") && !openMap)
            {
                openMap = true;
            }
            else if(Input.GetButtonDown("Map") && openMap)
            {
                openMap = false;
            }
    #15477
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    On my end, I seem to encounter a similar issue. I think either this was an existing issue that you’ve only encountered now.
    Or a change that I’ve made while updating the Metroidvania series has created this issue.

    I will have to get back to you on this after i bugtest, identify and code fix the issue, then we can check if it helps out your problem. Although, I hope you don’t mind that i get back to you on this during the next 2 days instead.

    #15478
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    Okay, of course there is no problem. This problem seems to have appeared after I created the Save function and opened the new game function. However, I put it aside because I was a little busy at the time. I asked it now that I thought about it. But maybe I’m remembering it wrong. Hope it helps you find the error

    #15479
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Okay, could you help me add some code to your scripts and check the console to see if everything’s in order? [The sceneNames saved in SaveData.cs is correct, and that your map’s are set correctly.]


    First, we’ll print a message to find out if our saved scene names are correct. If the message printed has been all the scenes that we have actually passed through.

    PlayerController.cs

        void GetInputs()
        {
            if (Input.GetButtonDown("Map") && !openMap)
            {
                openMap = true;
                var count = string.Join(", ", SaveData.Instance.sceneNames);
                print(count);
            }
            else if (Input.GetButtonDown("Map") && openMap)
            {
                openMap = false;
            }
        }

    Then, we’ll print the MapManager’s setting of each map. Which maps the script turns off and on.

    MapManager.cs

        void UpdateMap()
        {
            Debug.Log("updated");
            var savedScenes = SaveData.Instance.sceneNames;
    
            for(int i = 0; i < maps.Length; i++)
            {
                if(savedScenes.Contains("Cave_" + (i + 1))) //this is i + 1 as arrays start from 0
                {
                    maps[i].SetActive(true);
                    print("on: " + maps[i]);
                }
                else
                {
                    maps[i].SetActive(false);
                    print("off: " + maps[i]);
                }
            }
        }

    First. Try those 2 changes and check what appears in the console. When you do test it out, do it while standing on your save point/bench after interacting with it, and don’t move out of it’s collider.

    This is because for your map to update, the bench has to be interacted with and opened while it is interacted with.

    After you are done with setting up the prints and seeing how it works. We’ll then move on to make your maps actually update properly without having to stand on your bench and activating it to update.


    Due to our improvement on the bench script in Part 7.5, I had deactivated the Bench’s interacted bool whenever the player moved off the bench. Thus, anything like the Map which tries to check if the Bench is activated, can only do so while standing on the bench.

    Bench.cs

        private void OnTriggerExit2D(Collider2D _collision)
        {
            if (_collision.CompareTag("Player"))
            {
                interacted = false;
                inRange = false;
            }
        }

    Do tell me what your console prints out for your save points for me to find out more, or if the improvement to the Bench/Savepoint has solved the issue somehow.

    I will be posting the bench interacted update into our articles and videos regardless as it’s an improvement to the code.

    #15483
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    I recorded the video for you to watch

    #15484
    Joseph Tang
    Moderator
    Helpful?
    Up
    0
    ::

    Presuming that the print codes are working just fine, that means the problem is the code pertaining the sceneNames in SaveData.cs.

    Can i recommend that you put /* */ around all the methods in your SaveData.cs code? From ResetSavePoint() to DeleteAllData()?

    Because, it seems like all the previously saved data for sceneNames is being reset everytime before you save a new scene you just entered. As seen by whenever you entered a new scene it only prints out that current scene’s name.
    So if we remove the code with the function to remove sceneNames then we can deduce that if the problem still occurs, it must be from your sceneNames variable itself in SaveData.cs or the SaveScene() function in your GameManager.cs.

    It still is hard to conclude the issue for you as on my side it now works.

    #15485
    MI NI
    Bronze Supporter (Patron)
    Helpful?
    Up
    0
    ::

    If I put /* */ form setSavePoint() to DeleteAllData(),
    The following error occurs

    Assets\Script\GameManager.cs(57,31): error CS1061: ‘SaveData’ does not contain a definition for ‘DeleteAllSaveData’ and no accessible extension method ‘DeleteAllSaveData’ accepting a first argument of type ‘SaveData’ could be found (are you missing a using directive or an assembly reference?)

    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;
    
        //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
                }
            }
            LoadSceneData();
    
            //檢查重生點文件是否存在,否則將建立一個新文件
            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>();
            }
        }
    
        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(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 ResetSavePoint()
        {
            savePointSceneName = null;
            savePointPos = Vector2.zero;
        }
    
        public void ResetPlayerData()
        {
            playerHealth = PlayerController.Instance.maxHealth;
            playerMana = 0;
            lastScene = null;
            playerUnlockWallJump = false;
            playerUnlockDash = false;
            playeUnlockAirJump = false;
            playerUnlockSideSpell = false;
        }
    
        public void ResetSceneData()
        {
            sceneName.Clear();
        }
        
        public void DeleteScenesData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.scenes.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("Scenes data deleted.");
            }
            ResetSceneData();
        }
    
        public void DeletePlayerData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.player.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("Player save data deleted.");
            }
            ResetPlayerData();
        }
    
        public void DeleteSavePointData()//刪除資料
        {
            string path = Application.persistentDataPath + "/save.savePoint.data";
            if (File.Exists(path))
            {
                File.Delete(path);
                Debug.Log("SavePoint save data deleted.");
            }
            ResetSavePoint();
        }
    
        public void DeleteAllSaveData()
        {
            DeleteScenesData();
            DeleteSavePointData();
            DeletePlayerData();
        }
        */
    }
    
Viewing 15 posts - 1 through 15 (of 71 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: