游戏的存档和读档

1、保存的数据类:

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4
 5 [System.Serializable]
 6 public class Save
 7 {
 8     public List<int> livingTargetPosition = new List<int>();       //用来保存有怪物的位置信息
 9     public List<int> livingMonsterType = new List<int>();          //保存生成的怪物类型
10
11     public int shootNumebr=0;           //射击数
12     public int score = 0;        //分数
13 }

 

2、游戏管理器,用来管理游戏的保存和加载

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.UI;
  5 using System.IO;
  6 using System.Runtime.Serialization.Formatters.Binary;           //二进制转换器
  7 using LitJson;              //json的命名空间引入
  8 using System.Xml;           //引入xml的命名空间
  9
 10 public class GameManager : MonoBehaviour
 11 {
 12     private static GameManager _instance;
 13     public static GameManager Instace
 14     {
 15         get
 16         {
 17             return _instance;
 18         }
 19         set
 20         {
 21             _instance = value;
 22         }
 23     }
 24     private void Awake()
 25     {
 26         _instance = this;
 27
 28     }
 29
 30     public GameObject MenuGameObject;              //菜单游戏物体
 31     public GameObject[] targets;                   //每个格子都会有怪物生成,则要一一获取
 32     public bool IsPause = true;                     //默认菜单面板显示出来就是暂停状态
 33
 34     private void Start()
 35     {
 36         IsPause = true;
 37         Pause();                                    //默认菜单面板显示出来就是暂停状态
 38     }
 39
 40     private void Update()
 41     {
 42         if (Input.GetKeyDown(KeyCode.Escape))
 43         {
 44             Pause();                         //当按下了ESC键就调出菜单面板
 45         }
 46     }
 47
 48     /// <summary>
 49     /// 通过生成的游戏数据,然后创建保存类,将相关的数据写到Sava类中进行保存
 50     /// //只要调用这个方法,就会得到一个保存好数据的Save类
 51     /// </summary>
 52     /// <returns></returns>
 53     private Save CreateSave()
 54     {
 55         Save save = new Save();     //先创建这个对象
 56         foreach (GameObject targetGo in targets)
 57         {
 58             TargetManager targetManager = targetGo.GetComponent<TargetManager>();
 59             if(targetManager.activateMoster!=null)
 60             {
 61                 //如果有不为空的,也就是在游戏场景中生成了的,
 62                 save.livingTargetPosition.Add(targetManager.targetPosition);            //则要进行保存
 63                 save.livingMonsterType.Add(targetManager.activateMoster.GetComponent<MosterManager>().mosterType);  //保存怪物类型
 64             }
 65         }
 66         save.shootNumebr = UIManager.Instance.shootNumber;
 67         save.score = UIManager.Instance.scoreNumber;                //将分数和射击数进行保存
 68
 69         return save;
 70     }
 71     /// <summary>
 72     /// 通过读档,将得到的数据运用到游戏中,分数、射击数、怪物位置、怪物类型
 73     /// </summary>
 74     /// <param name="save">读取到的文件类</param>
 75     private void SetGame(Save save)
 76     {
 77         foreach (GameObject targetGo in targets)
 78         {
 79             targetGo.GetComponent<TargetManager>().UpdateMoster();      //通过数据读取来设计游戏中的场景时,要先将场景中有的进行清空
 80         }
 81
 82         for (int i = 0; i < save.livingTargetPosition.Count; i++)
 83         {
 84             int position = save.livingTargetPosition[i];            //得到在哪个格子里面进行生成
 85             int type = save.livingMonsterType[i];                   //得到生成那种类型的
 86             targets[position].GetComponent<TargetManager>().ActivateMonsterByType(type);        //通过怪物下标来进行生成
 87         }
 88
 89         UIManager.Instance.shootNumber = save.shootNumebr;
 90         UIManager.Instance.scoreNumber = save.score;                //更新得分和成绩
 91     }
 92
 93
 94
 95
 96     //二进制:存档和读档
 97     private void SaveByBin()
 98     {
 99         //1、首先得到要保存的Save类
100         Save save = CreateSave();
101         //2、创建一个二进制转化程序
102         BinaryFormatter binF = new BinaryFormatter();
103         //3、得到要保存数据的数据流
104         FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/Bin.txt");
105         //4、进行序列化,写入
106         binF.Serialize(fileStream, save);
107         //5、关闭
108         fileStream.Close();
109
110         if(File.Exists((Application.dataPath + "/StreamingFile" + "/Bin.txt")))
111         {
112             //如果保存成功了,显示保存成功的提示
113             UIManager.Instance.Message("保存成功");
114         }
115     }
116
117     private void LoadByBin()
118     {
119         //1、先判断存档文件是否存在
120         if(File.Exists(Application.dataPath + "/StreamingFile" + "/Bin.txt"))
121         {
122             //2、创建二进制转换器
123             BinaryFormatter binf = new BinaryFormatter();
124             //3、得到文件流
125             FileStream fileStrem = File.Open(Application.dataPath + "/StreamingFile" + "/Bin.txt", FileMode.Open);
126             //4、通过二进制逆转换器得到数据
127             Save save = (Save)binf.Deserialize(fileStrem);      //得到数据
128             //5、关闭
129             fileStrem.Close();
130             //6、将数据进行保存
131             SetGame(save);
132
133             UIManager.Instance.Message("读档成功");
134         }
135         else
136         {
137             UIManager.Instance.Message("文档不存在");
138         }
139     }
140
141
142     //XML:存档和读档
143     private void SaveByXml()
144     {
145         //1、创建save对象
146         Save save = CreateSave();
147         //2、创建XML文件的存储路径
148         string filePath = Application.dataPath + "/StreamingFile" + "/byXml.xml";
149         //3、创建XML文档
150         XmlDocument xmlDoc = new XmlDocument();
151         //4、创建根节点,名字为Save,注意,一个XML文档只有一个根节点,就和html语言一样
152         XmlElement root = xmlDoc.CreateElement("Save");
153         //5、设置根节点的属性,也可以不设置
154         root.SetAttribute("namne","saveFile");
155
156         //6、创建XmlElement
157         XmlElement target;
158         XmlElement targetPosition;
159         XmlElement targetType;
160
161         for (int i = 0; i < save.livingTargetPosition.Count; i++)
162         {
163             target = xmlDoc.CreateElement("Target");
164
165             //创建其中一个属性 设置innertext的值
166             targetPosition = xmlDoc.CreateElement("targetPosition");
167             targetPosition.InnerText = save.livingTargetPosition[i].ToString();
168
169             targetType = xmlDoc.CreateElement("targetType");
170             targetType.InnerText = save.livingMonsterType[i].ToString();
171
172             //设置层级关系
173             target.AppendChild(targetPosition);
174             target.AppendChild(targetType);
175             root.AppendChild(target);
176         }
177         XmlElement UI;
178         XmlElement shootNumber;
179         XmlElement score;
180
181         UI = xmlDoc.CreateElement("UI");
182         shootNumber = xmlDoc.CreateElement("ShootNumber");
183         score = xmlDoc.CreateElement("Score");
184
185         //存入数据
186         shootNumber.InnerText = save.shootNumebr.ToString();
187         score.InnerText = save.score.ToString();
188
189         //设置层级关系
190         UI.AppendChild(shootNumber);
191         UI.AppendChild(score);
192         root.AppendChild(UI);
193
194         //将根节点添加到xml文档中
195         xmlDoc.AppendChild(root);
196         //保存xml文档
197         xmlDoc.Save(filePath);
198
199         if(File.Exists(filePath))
200         {
201             UIManager.Instance.Message("保存成功");
202         }
203
204     }
205     private void LoadByXml()
206     {
207         string filePath= Application.dataPath + "/StreamingFile" + "/byXml.xml";
208         //如果存在文件的话
209         if(File.Exists(filePath))
210         {
211             Save save = new Save();
212             //加载XML文档
213             XmlDocument xmlDoc = new XmlDocument();
214             xmlDoc.Load(filePath);
215             //通过节点名称来获取元素,注意,文档中会有多个该节点,结果为XmlNodeList类型
216             XmlNodeList targets =xmlDoc.GetElementsByTagName("Target");
217             if(targets.Count!=0)
218             {
219                 for (int i = 0; i < targets.Count; i++)
220                 {
221                     //每一个target节点下面还有子节点,数据存在了对应的子节点下面
222                     XmlNode targetPosition = targets[i].ChildNodes[0];
223                     int targetPositionValue = int.Parse(targetPosition.InnerText);
224                     save.livingTargetPosition.Add(targetPositionValue);
225
226                     XmlNode targetType = targets[i].ChildNodes[1];
227                     int targetTypeValue = int.Parse(targetType.InnerText);
228                     save.livingMonsterType.Add(targetTypeValue);
229
230                 }
231             }
232
233             XmlNodeList UI = xmlDoc.GetElementsByTagName("UI");
234             if(UI.Count!=0)
235             {
236                 foreach (XmlNode ui in UI)
237                 {
238                     XmlNode shootNumber = ui.ChildNodes[0];
239                     int shootNumberValue = int.Parse(shootNumber.InnerText);
240                     save.shootNumebr = shootNumberValue;
241
242                     XmlNode score = ui.ChildNodes[1];
243                     int scoreValue = int.Parse(score.InnerText);
244                     save.score = scoreValue;
245                 }
246             }
247
248             //将得到的数据进行应用
249             SetGame(save);
250
251             UIManager.Instance.Message("文档加载成功");
252         }
253         else
254         {
255             UIManager.Instance.Message("文档不存在");
256         }
257
258
259
260     }
261
262
263     //JSON:存档和读档
264     private void SaveByJson()
265     {
266         //1、创建save对象
267         Save save = CreateSave();
268         //2、得到要放置json文件的地址
269         string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
270         //3、将save对象转换为json字符串
271         string saveJsonString = JsonMapper.ToJson(save);
272         //4、 //设置为写入的文件流
273         StreamWriter writer = new StreamWriter(filePath);
274         //5、写入
275         writer.Write(saveJsonString);
276         //6、关闭
277         writer.Close();
278         if(File.Exists(Application.dataPath + "/StreamingFile" + "/byJson.json"))
279         {
280             UIManager.Instance.Message("保存成功");
281         }
282
283
284     }
285     private void LoadByJson()
286     {
287         string filrPath = Application.dataPath + "/StreamingFile" + "/byJson.json";
288         if(File.Exists(filrPath))
289         {
290             //1、如果文件存在
291             StreamReader reader = new StreamReader(filrPath);
292             //2、通过读取数据流读到json文件中的信息,转化为字符串
293             string loadJsonString = reader.ReadToEnd();         //读取到结尾
294             //3、将json文件转化为save对象
295             Save save = JsonMapper.ToObject<Save>(loadJsonString);
296             //4、将数据应用到游戏中
297             SetGame(save);
298             UIManager.Instance.Message("读取成功");
299         }
300         else
301         {
302             UIManager.Instance.Message("文档不存在");
303         }
304
305     }
306
307     /// <summary>
308     /// 暂停游戏
309     /// </summary>
310     private void Pause()
311     {
312         MenuGameObject.SetActive(true);
313         IsPause = true;
314         Time.timeScale = 0;         //暂停游戏
315         Cursor.visible = true;
316     }
317
318
319     /// <summary>
320     /// 非暂停状态
321     /// </summary>
322     private void UpPause()
323     {
324         IsPause = false;
325         MenuGameObject.SetActive(false);
326         Time.timeScale = 1;         //继续进行游戏
327         Cursor.visible = false;
328     }
329
330     /// <summary>
331     /// 继续游戏
332     /// </summary>
333     public void OnContinueGameButtonClick()
334     {
335         UpPause();
336     }
337
338     /// <summary>
339     /// 退出游戏
340     /// </summary>
341     public void OnQuietButtonClick()
342     {
343     #if UNITY_EDITOR
344          UnityEditor.EditorApplication.isPlaying = false;
345     # else
346          Application.Quit();
347     #endif
348     }
349
350     /// <summary>
351     ///新游戏
352     /// </summary>
353     public void OnNewGameButtonClick()
354     {
355         foreach (GameObject target in targets)
356         {
357             target.GetComponent<TargetManager>().UpdateMoster();            //对场景中的每一个敌人进行消息传递,进行更新
358         }
359         UIManager.Instance.shootNumber = 0;
360         UIManager.Instance.scoreNumber = 0;         //将分数进行清零
361         UpPause();
362     }
363
364     /// <summary>
365     /// 保存数据
366     /// </summary>
367     public void OnSaveButtonClick()
368     {
369         UIManager.Instance.Message("");
370         //SaveByBin();            //二进制保存
371         //SaveByJson();
372         SaveByXml();
373         StartCoroutine(HideMessage());
374     }
375
376     /// <summary>
377     /// 加载数据
378     /// </summary>
379     public void OnLoadButtonClick()
380     {
381         UIManager.Instance.Message("");
382         //LoadByBin();
383         //LoadByJson();
384         LoadByXml();
385         StartCoroutine(HideMessage());
386     }
387
388     /// <summary>
389     /// 在一定时间内将帮助文档进行隐藏
390     /// </summary>
391     /// <returns></returns>
392    IEnumerator HideMessage()
393     {
394         yield return new WaitForSeconds(1.0f);
395         UIManager.Instance.message_Text.gameObject.SetActive(false);
396     }
397 }

3、显示TargetManager和UIManager两个类方便阅读

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.UI;
  5
  6 public class UIManager : MonoBehaviour
  7 {
  8
  9     private static UIManager _instace;
 10     public static UIManager Instance
 11     {
 12         set
 13         {
 14             _instace = value;
 15         }
 16         get
 17         {
 18             return _instace;
 19         }
 20     }
 21     private void Awake()
 22     {
 23         _instace = this;
 24     }
 25
 26     public Text shootNumber_Text;
 27     public Text scoreNumber_Text;
 28     public Toggle musicToggle;
 29     public Text message_Text;           //用来显示保存、加载成功的
 30
 31     public int shootNumber = 0;
 32     public int scoreNumber = 0;
 33
 34     public AudioSource music;
 35
 36
 37     private void Start()
 38     {
 39         message_Text.gameObject.SetActive(false);
 40     }
 41
 42     private void Update()
 43     {
 44         UpdateUI();     //更新UI显示
 45
 46
 47
 48         //如果存在声音控制的键值
 49         if(PlayerPrefs.HasKey("MusicOn"))
 50         {
 51             if(PlayerPrefs.GetInt("MusicOn")==0)
 52             {
 53                 musicToggle.isOn = false;
 54                 music.enabled = false;
 55             }
 56             else if(PlayerPrefs.GetInt("MusicOn")==1)
 57             {
 58                 musicToggle.isOn = true;
 59                 music.enabled = true;
 60             }
 61         }
 62         //如果不存在这个键的话,就默认设置为播放状态
 63         else
 64         {
 65             musicToggle.isOn = true;
 66             music.enabled = true;
 67         }
 68
 69
 70     }
 71
 72
 73     /// <summary>
 74     /// 声音开光控制
 75     /// 使用了PlayerPrefs的保存方法来进行保存
 76     /// </summary>
 77     public void MusicSwitch()
 78     {
 79         if(musicToggle.isOn==true)
 80         {
 81             music.enabled = true;
 82             PlayerPrefs.SetInt("MusicOn", 1);           //为1表示播放音乐,为0表示暂停音乐
 83         }
 84         else
 85         {
 86             music.enabled = false;
 87             PlayerPrefs.SetInt("MusicOn", 0);
 88         }
 89
 90         PlayerPrefs.Save();         //注意,在设置完值后,一定要进行保存,否则结果是无法进行保存的
 91     }
 92
 93
 94
 95
 96
 97     /// <summary>
 98     /// 更新Ui显示的方法
 99     /// </summary>
100     private void UpdateUI()
101     {
102         shootNumber_Text.text = shootNumber.ToString();
103         scoreNumber_Text.text = scoreNumber.ToString();
104     }
105     /// <summary>
106     /// 增加射击数的
107     /// </summary>
108     public void AddShootNumber()
109     {
110         shootNumber += 1;
111     }
112
113     /// <summary>
114     /// 增加分数的
115     /// </summary>
116     public void AddScoreNumber()
117     {
118         scoreNumber += 1;
119     }
120
121     /// <summary>
122     /// 显示加载、保存成功的提示消息的
123     /// </summary>
124     /// <param name="message">保存成功、保存失败</param>
125     public void Message(string message)
126     {
127         message_Text.text = message;
128         message_Text.gameObject.SetActive(true);
129     }
130 }
  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4
  5 public class TargetManager : MonoBehaviour
  6 {
  7     //这里不能用单例模式,因为在游戏中会生成多个相同的对象,
  8     //到后面就不能正确的知道是那个TargetManager了
  9     //private static TargetManager _instance;
 10     //public static TargetManager Instance
 11     //{
 12     //    get
 13     //    {
 14     //        return _instance;
 15     //    }
 16     //    set
 17     //    {
 18     //        _instance = value;
 19     //    }
 20     //}
 21     //private void Awake()
 22     //{
 23     //    _instance = this;
 24     //}
 25
 26     public GameObject[] mosters;
 27     public GameObject activateMoster=null;         //这个是用来取得当前实例出来的怪物
 28     public int targetPosition;          //用来设置怪物的生成位置,要被保存的
 29
 30     private void Start()
 31     {
 32         //一开始先做预判的处理
 33         foreach (GameObject moster in mosters)
 34         {
 35             moster.GetComponent<BoxCollider>().enabled = false;
 36             moster.SetActive (false);
 37         }
 38         StartCoroutine(AliveTiemr());
 39     }
 40
 41
 42
 43     /// <summary>
 44     /// 等待多久进行怪物的生成的协程
 45     /// </summary>
 46     /// <returns></returns>
 47     IEnumerator AliveTiemr()
 48     {
 49         yield return new WaitForSeconds(Random.Range(1, 5));            //等待个随机1-4秒再生成
 50         ActivateMoster();
 51         StartCoroutine(DeathTimer());
 52     }
 53
 54     /// <summary>
 55     /// 控制怪物在生成一段时间后自动进行消失
 56     /// </summary>
 57     /// <returns></returns>
 58     IEnumerator DeathTimer()
 59     {
 60         yield return new WaitForSeconds(Random .Range(3f,8.0f));
 61         DeActivateMoster();
 62     }
 63
 64
 65
 66     /// <summary>
 67     /// 将小怪物进行激活
 68     /// </summary>
 69     private void ActivateMoster()
 70     {
 71         int index = Random.Range(0, mosters.Length);            //取得随机的生成怪物的下标
 72         activateMoster = mosters[index];
 73         activateMoster.SetActive(true);
 74         activateMoster.GetComponent<BoxCollider>().enabled = true;
 75     }
 76
 77     /// <summary>
 78     /// 将怪物进行隐藏
 79     /// </summary>
 80     private void DeActivateMoster()
 81     {
 82         if(activateMoster!=null)
 83         {
 84             activateMoster.GetComponent<BoxCollider>().enabled = false;
 85             activateMoster.SetActive(false);
 86             activateMoster = null;
 87         }
 88        StartCoroutine(AliveTiemr());
 89
 90     }
 91
 92     /// <summary>
 93     /// 当怪物被打死后,让外界(MosterManager)进行调用重新再生成一波敌人
 94     /// </summary>
 95     public void UpdateMoster()
 96     {
 97         StopAllCoroutines();            //现将所有的协程进行暂停,避免出现协程没运行完,就开始生成下一波怪物了
 98         if (activateMoster!=null)
 99         {
100             activateMoster.GetComponent<BoxCollider>().enabled = false;
101             activateMoster.SetActive(false);
102             activateMoster = null;
103         }
104         StartCoroutine(AliveTiemr());
105     }
106
107
108     /// <summary>
109     /// 通过指定的怪物类型来进行怪物的生成
110     /// 放在游戏加载的时候被调用
111     /// </summary>
112     /// <param name="type">怪物下标类型</param>
113     public void ActivateMonsterByType(int type)
114     {
115         StopAllCoroutines();            //先停止所有的协程
116         if(activateMoster!=null)
117         {
118             activateMoster.GetComponent<BoxCollider>().enabled = false;
119             activateMoster.SetActive(false);
120             activateMoster = null;
121         }
122         activateMoster = mosters[type];         //通过怪物类型来进行生成
123         activateMoster.SetActive(true);
124         activateMoster.GetComponent<BoxCollider>().enabled = true;
125         StartCoroutine(DeathTimer());           //怪物生成出来了,就要等待被删除了
126
127     }
128 }

4、希望可以帮助到大家,这也是自己的学习出来的,有错误希望大家帮忙指正。

【注意:】使用JSON的话要导入Json库!!!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{

private static UIManager _instace;
    public static UIManager Instance
    {
        set
        {
            _instace = value;
        }
        get
        {
            return _instace;
        }
    }
    private void Awake()
    {
        _instace = this;
    }

public Text shootNumber_Text;
    public Text scoreNumber_Text;
    public Toggle musicToggle;
    public Text message_Text;           //用来显示保存、加载成功的

public int shootNumber = 0;
    public int scoreNumber = 0;

public AudioSource music;

private void Start()
    {
        message_Text.gameObject.SetActive(false);
    }

private void Update()
    {
        UpdateUI();     //更新UI显示

//如果存在声音控制的键值
        if(PlayerPrefs.HasKey("MusicOn"))
        {
            if(PlayerPrefs.GetInt("MusicOn")==0)
            {
                musicToggle.isOn = false;
                music.enabled = false;
            }
            else if(PlayerPrefs.GetInt("MusicOn")==1)
            {
                musicToggle.isOn = true;
                music.enabled = true;
            }
        }
        //如果不存在这个键的话,就默认设置为播放状态
        else
        {
            musicToggle.isOn = true;
            music.enabled = true;
        }

}

/// <summary>
    /// 声音开光控制
    /// 使用了PlayerPrefs的保存方法来进行保存
    /// </summary>
    public void MusicSwitch()
    {
        if(musicToggle.isOn==true)
        {   
            music.enabled = true;
            PlayerPrefs.SetInt("MusicOn", 1);           //为1表示播放音乐,为0表示暂停音乐
        }
        else
        {        
            music.enabled = false;
            PlayerPrefs.SetInt("MusicOn", 0);
        }

PlayerPrefs.Save();         //注意,在设置完值后,一定要进行保存,否则结果是无法进行保存的
    }

/// <summary>
    /// 更新Ui显示的方法
    /// </summary>
    private void UpdateUI()
    {
        shootNumber_Text.text = shootNumber.ToString();
        scoreNumber_Text.text = scoreNumber.ToString();
    }
    /// <summary>
    /// 增加射击数的
    /// </summary>
    public void AddShootNumber()
    {
        shootNumber += 1;
    }

/// <summary>
    /// 增加分数的
    /// </summary>
    public void AddScoreNumber()
    {
        scoreNumber += 1;
    }

/// <summary>
    /// 显示加载、保存成功的提示消息的
    /// </summary>
    /// <param name="message">保存成功、保存失败</param>
    public void Message(string message)
    {
        message_Text.text = message;
        message_Text.gameObject.SetActive(true);
    }
}

原文地址:https://www.cnblogs.com/zhh19981104/p/9141070.html

时间: 2024-11-09 04:44:28

游戏的存档和读档的相关文章

SIKI_Unity_2_入门_通过实例学习游戏的存档和读档

SIKI_Unity_2_入门_通过实例学习游戏的存档和读档 任务5:创建设计目标 Animation的直接使用: 将Animation组件直接挂载在游戏物体上即可播放 脚本控制: 方法1: 直接在Inspector面板给Animation的Animations集合赋值动画a和b通过animation.clip = a或animation.clip = b后进行animation.Play()即可播放相关动画注意:这种情况下如果在Inspector面板的Animations集合中没有动画b,那么

数据存档和读档三种方式

using System.Collections;using System.Collections.Generic;using UnityEngine;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using LitJson;using System.Xml; public class GameManager : MonoBehaviour{    public static GameManager _i

Unity开发之存档和读档的三种实现方式

此文内容源自siki学院视频,仅供学习!视频链接地址:http://www.sikiedu.com/course/129 工程使用Unity 2017.3.0f3 (64-bit) 老司机读博客,了解存档读档主体实现方式即可,仅供借鉴参考,菜鸟可以去文章结尾下载源码,或者去上面的链接直接观看视频..... 首先,创建一个Save类用于保存数据 [System.Serializable]public class Save{ public List<int> livingTargetPositio

Unity - 存读档机制简析

本文旨在于简要分析Unity中的两种存档机制,即:PlayerPrefs数据持久化方法及Serialization数据序列化方法 较比于源项目,我另加了JSON方法.XML方法等及一些Unity设置,更便于读者在使用中理解Unity的存档机制.核心脚本为Game.cs 源项目地址:How to Save and Load a Game in Unity - raywenderlich 个人项目地址:BattleSave - SouthBegonia 一.PlayerPrefs 数据持久化方法 存

项目实战(读档的错误捕捉)

读取游戏数据档是游戏并不可少的一个功能,一般我们搭建Unity环境的时候, 我们会准备一些类来负责数据的读取操作.  我来介绍下我们公司读档遇到的问题. 首先是类的介绍 BaseData 读档的父类 BaseDataManager  读档管理类(BaseDataSecondLoad方法中读取每一个档) xxxx:BaseData 每一个档对应的操作类 Load(string filePath) 方法里面具体怎么读每一个档   =.=来看下我们读档操作是怎么写的.貌似看起来没有问题. 如果环境是这

【腾讯GAD暑期训练营游戏程序班】游戏场景管理作业说明文档

场景管理作业说明文档                              用了八叉树的算法,测出三层时最快,区域范围内物体数量为21块,控制台打印出的结果如图所示: 场景物体:游戏中,所有具有空间属性的物体游戏场景:<围棋>二维表<进击的围棋><围棋世界>基于空间分组的场景管理的进一步优化进一步分组四叉树视锥范围剔除非可见区域当前必要场景区域 动态加载谷歌 可感知即存在 不可感知即不存在 场景加载

C++之路进阶——最小费用最大流(支线剧情)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 542  Solved: 332[Submit

BZOJ3876[AHOI2014]支线剧情

Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情. 这些游戏往往都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点.当然如果为0,则说明i号剧情点是游戏的一个结局了. JYY观看一个支线剧情需要一定的时间

bzoj 3876 [Ahoi2014]支线剧情(有上下界的最小费用流)

3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 484  Solved: 296[Submit][Status][Discuss] Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情. [问题描述] JYY现在所玩的R