Forum begins after the advertisement:


[Part 7] Map problem

Viewing 15 posts - 16 through 30 (of 71 total)
  • Author
    Posts
  • #15486
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    Oh, I think I forgot to delete the code in GameManager. I will get back to you after testing it.

    #15488
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    After I tested it I think it got a little complicated and I don’t know how to explain it.
    If you need me to do more testing, I’ll be happy to oblige

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

    Hmm… Okay this is getting nowhere, can you quickly do a search through all your scripts by pressing “Control + F” then selecting the dropdown menu below the searchbar and selecting “Current Project” from “Current Document”.

    Then Search for “scenenames”. Afterwards, can you tell me only instances of sceneNames specifically you see.

    Not the code that have scene names as part of the full name but instead the lines that call sceneNames the variable.

    This is because i just need to confirm that it’s only between SaveScene() in GameManager.cs and the variable itself in SaveData.cs. If it is. I recommend we try redoing that code by removing, and rewriting the code again later.

    #15490
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    Is it like this?

    View post on imgur.com

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

    Yep, that’s right. So we can confirm that everything is only between SaveData.cs and GameManager.cs but your code is perfectly fine. Can you help me check one thing. This time you need only just walk between scenes.

    You can remove the previous print codes i asked you to put and put this instead in GameManager.cs

        public void SaveScene()
        {
            //獲取當前場景名稱
    
            var count = string.Join(", ", SaveData.Instance.sceneNames);
            print(count);
            print(SaveData.Instance.sceneNames.Count);
    
            string currentSceneName = SceneManager.GetActiveScene().name;
            SaveData.Instance.sceneName.Add(currentSceneName);
            Debug.Log("saved" + currentSceneName);
    
            var count = string.Join(", ", SaveData.Instance.sceneNames);
            print(count);
            print(SaveData.Instance.sceneNames.Count);
        }

    This is likely the only area of code where the sceneNames are deleted and stays the same. We’re checking if the sceneNames here are actually deleted, then counting the number of elements in the hashset to check if that number stays the same or increases when we add and we simply just arent printing things correctly.

    #15492
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

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

    Your scene data is resetting everytime you enter a scene. May i affirm that in your scene, you do not have a game object that you placed the SaveData script onto right?

    #15495
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    I checked all my game objects and made sure none placed SaveData.cs
    But I would like to ask, when there are a large number of game objects, is there a way to know which objects use this script?

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

    In the Scene Hierarchy search bar you can use “t:” followed by the name of the component you are looking for to see all objects that contain said component.

    For instance you can use:
    “t:button” to find all objects that contain a button component,
    “t:boxcollider2d” to find all box collider 2d’s in the scene.
    “t:gamemanager” to find all objects with the GameManager script.
    or “t:savedata” to find savedata scripts.

    #15497
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    Thanks for your tutorial, I used t:SaveData and double-checked that I did not place SaveData.cs in any game object

    #15500
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    MI NI, can you try changing the SaveData object to be a class instead of a struct. See if it fixes the issue.

    #15501
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    After I changed struct to class, an error occurred in the game

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

    After looking through your project i’ve found the issue.

    Disappointingly, It had slipped my mind to not realize that your code was slightly different from ours. It’s the inclusion of this piece of code:

        public void Initialize() //ªì©l¤Æ
        {
    
            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();
        }
    
        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();
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneName.Add(_sceneName);
                    }
                }
            }
            else
            {
                sceneName = new HashSet();
            }
        }

    The thing is, we did not actually implement a way to save the scene names like we do player data and i had also forgotten to add that in for the series. So these 2 methods were unfamiliar yet i thought they were normal.

    In any case, what the issue is, your LoadSceneData() is being called in Initialize. The issue with that is the fact that your GameManager.cs calls your SaveData.cs Initialize() method in Awake().

    Thus every scene you enter, your SaveData.cs will call LoadSceneData().

    The real problem comes due to the fact that you have no way of calling SaveSceneData(). Meaning, that your sceneNames data, that you load through LoadSceneData() every time you enter a scene, is empty.
    Thereby causing your sceneNames to be null everytime you enter a new scene and thus causing your maps to never progress.


    If you want to keep your methods, since they will be good in saving your data, you should just remove that one call for LoadSceneData() in Initialize(), I marked it above, and also look towards calling SaveSceneData() and LoadSceneData() somewhere else more appropriate, like in your SavePlayerData().

    #15503
    MI NI
    Level 13
    Participant
    Helpful?
    Up
    0
    ::

    After modifying the LoadSceneData();, it worked, but I found that after restarting the game, the map resets.
    I tried moving SaveSceneData() and LoadSceneData() into SavePlayerData() but it doesn’t work. I want to know how I should modify it to be successful.

    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);
    
                //地圖TEST
                writer.Write(sceneName.Count);
                foreach (string sceneName in sceneName)
                {
                    writer.Write(sceneName);
                }
    
            }
        }
    
        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");
    
                    //地圖TEST
                    int sceneCount = reader.ReadInt32();
                    sceneName = new HashSet<string>();
                    for (int i = 0; i < sceneCount; i++)
                    {
                        string _sceneName = reader.ReadString();
                        sceneName.Add(_sceneName);
                    }
    
                    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;
    
                //地圖TEST
                sceneName = new HashSet<string>();
            }
        }
        
    
        /*
        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();
        }
        */
    }
    
    #15504
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    If you take a look at your code again, your LoadSceneData() method code is wrong.

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

    That line that you moved into LoadPlayerData() is a problem because what you are doing is resetting all saved maps every time you want to load them.

Viewing 15 posts - 16 through 30 (of 71 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: