Unity类银河战士恶魔城学习总结(P142 Save System 保存系统)
【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);
else
instance = 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);
else
instance = this;
}
public bool HaveEnoughMoney(int _price)//是否有钱去买技能
{
if (_price > currency)
{
Debug.Log("没有足够的钱");
return false;
}
else
currency -= _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;
}
}