【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节实现了保存系统的初步建立
windows系统最终货币的保存文件被保存在如下路径下
SaveManager.cs
功能概述
SaveManager
是一个单例模式的组件,负责以下任务:
- 管理游戏存档数据:存储和处理当前的游戏数据。
- 与游戏中的数据模块交互:通过接口
ISaveManager
收集实现该接口的脚本,以便统一管理存储和加载逻辑。 - 文件操作:通过
FileDataHandler
类完成数据的实际存储和加载到磁盘。
1. 单例模式
作用:确保 SaveManager
只有一个实例,全局共享。
2. Start()函数
- 逻辑:
- 创建一个文件数据处理器
dataHandler
,负责读写存档数据。 - 收集所有实现了
ISaveManager
接口的脚本。 - 自动加载游戏数据。
- 创建一个文件数据处理器
- 生命周期方法:
OnApplicationQuit()
在游戏退出时自动保存游戏。
3. 存档管理逻辑
(1)新建存档:NewGame()函数
作用:创建一个新的 GameData
对象,作为空白存档。
(2)加载存档:LoadGame()函数
- 调用
dataHandler.Load()
从文件中加载存档。 - 如果没有找到存档,则调用
NewGame()
创建一个空白存档。 - 遍历所有
ISaveManager
实现,调用它们的LoadData
方法,将存档数据同步到游戏对象中。
(3)保存存档:SaveGame()函数
- 遍历所有实现
ISaveManager
的脚本,调用它们的SaveData
方法,将游戏状态保存到gameData
中。 - 将
gameData
写入磁盘文件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;//2024.11.25
public class SaveManager : MonoBehaviour
{public static SaveManager instance;[SerializeField] private string fileName;private GameData gameData;private List<ISaveManager> saveManagers = new List<ISaveManager>();private FileDataHandler dataHandler;private void Awake(){if (instance != null)Destroy(instance.gameObject);elseinstance = this;}private void Start(){dataHandler = new FileDataHandler(Application.persistentDataPath,fileName);saveManagers = FindAllSaveManagers();LoadGame();}public void NewGame(){gameData = new GameData();}public void LoadGame(){gameData = dataHandler.Load();if (this.gameData == null){Debug.Log("没有找到存档");NewGame();}foreach (ISaveManager saveManager in saveManagers){saveManager.LoadData(gameData);}}public void SaveGame(){foreach(ISaveManager saveManager in saveManagers){saveManager.SaveData(ref gameData);}dataHandler.Save(gameData);}private void OnApplicationQuit(){SaveGame();}private List<ISaveManager> FindAllSaveManagers(){IEnumerable<ISaveManager> saveManagers = FindObjectsOfType<MonoBehaviour>().OfType<ISaveManager>();return new List<ISaveManager>(saveManagers);}
}
GameData.cs
用于存放需要保存的数据的一个类!!!
这里只写了货币
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//2024.11.25
[System.Serializable]
public class GameData
{public int currency;public GameData(){this.currency = 0;}}
ISaveManager.cs
类似于一个接口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public interface ISaveManager
{void LoadData(GameData _data);void SaveData(ref GameData _data);}
PlayerManager.cs
进行了一些实例化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//P63,制作玩家管理器和技能管理器
//可以在SkeletonBattleState中通过PlayerManager.instance.player.transform获取到玩家的位置
public class PlayerManager : MonoBehaviour,ISaveManager
{//全局访问public static PlayerManager instance;//单例模式public Player player;public int currency;private void Awake(){if (instance != null)Destroy(instance.gameObject);elseinstance = this;}public bool HaveEnoughMoney(int _price)//是否有钱去买技能{if (_price > currency){Debug.Log("没有足够的钱");return false;}elsecurrency -= _price;return true;}public int GetCurrency() => currency;//返回当前的货币数量public void LoadData(GameData _data){currency = _data.currency;}public void SaveData(ref GameData _data){_data.currency = this.currency; }
}
FileDataHandler.cs
不必懂
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;public class FileDataHandler
{private string dataDirPath = "";private string dataFileName = "";public FileDataHandler(string _dataDirPath, string _dataFileName){dataDirPath = _dataDirPath;dataFileName = _dataFileName;}public void Save(GameData _data){string fullPath = Path.Combine(dataDirPath, dataFileName);try{Directory.CreateDirectory(Path.GetDirectoryName(fullPath));string dataToStore = JsonUtility.ToJson(_data, true);using (FileStream stream = new FileStream(fullPath, FileMode.Create)){using (StreamWriter writer = new StreamWriter(stream)){writer.Write(dataToStore);}}}catch (Exception e){Debug.LogError("保存数据错误: " + fullPath + "\n" + e);}}public GameData Load()//同上{string fullPath = Path.Combine(dataDirPath, dataFileName);GameData loadData = null;if (File.Exists(fullPath)){try{string dataToLoad = "";using (FileStream stream = new FileStream(fullPath, FileMode.Open)){using (StreamReader reader = new StreamReader(stream)){dataToLoad = reader.ReadToEnd();}}loadData = JsonUtility.FromJson<GameData>(dataToLoad);}catch (Exception e){Debug.LogError("读取数据错误: " + fullPath + "\n" + e);}}return loadData;}
}