Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
FileDataHandler.cs
using System;
using System.IO;
using UnityEngine;
public class FileDataHandler
{
private string dataDirPath = "";
private string dataFileName = "";
public FileDataHandler(string _dataDirPath, string _dataFilePath)//构造函数拿到需要保存的位置和文件名称
{
dataDirPath = _dataDirPath;
dataFileName = _dataFilePath;
}
public void Save(GameData _data)
{
string fullPath = Path.Combine(dataDirPath, dataFileName);//合成路径函数 将位置和文件合并成实际的可以读取的路径
try//用try防止其报错
{
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));//通过路径创建出需要的文件,存在就不创建了
string dataToStore = JsonUtility.ToJson(_data, true);//将传过来的gameData转换成文本形式并且使其可读
using (FileStream stream = new FileStream(fullPath, FileMode.Create))//两个using 第一个进入文件使其变为可编写模式
{
using (StreamWriter writer = new StreamWriter(stream))//第二个拿到文件对其进行编辑
{
writer.Write(dataToStore);//写入函数
}
}
}
catch (Exception e)
{
Debug.LogError("Error on trying to save data to file " + 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(e);
}
}
return loadData;
}
}
ISaveManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface ISaveManager
{
void LoadData(GameData _data);
void SaveData(ref GameData _data);
}
SaveManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class SaveManager : MonoBehaviour
{
public static SaveManager instance;
[SerializeField] private string fileName;
GameData gameData;
private List<ISaveManager> saveManagers;
private FileDataHandler dataHandler;
private void Awake()
{
if (instance != null)
Destroy(instance);
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("No data");
NewGame();
}
foreach(ISaveManager saveManager in saveManagers)//循环调用所有的找到脚本的LoadData和SaveData到,这样便可以将所有的数据汇聚到gameData中,并从中拿到data
{
saveManager.LoadData(gameData);
}
Debug.Log("Loaded currency " + gameData.currency);
}
public void SaveGame()循环调用所有的找到脚本的LoadData和SaveData到,这样便可以将所有的数据汇聚到gameData中,并从中拿到data
{
foreach(ISaveManager saveManager in saveManagers)
{
saveManager.SaveData(ref gameData);
}
dataHandler.Save(gameData);
}
private void OnApplicationQuit()
{
SaveGame();
}
private List<ISaveManager> FindAllSaveManagers()//全局寻找带ISave的脚本的函数
{
IEnumerable<ISaveManager> saveManager = FindObjectsOfType<MonoBehaviour>().OfType<ISaveManager>();
return new List<ISaveManager>(saveManager);
}
}
GameData.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class GameData
{
public int currency;
public GameData()
{
this.currency = 0;
}
}
PlayerManager.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class PlayerManager : MonoBehaviour, ISaveManager
{
public static PlayerManager instance;
public Player player;//这是通过在外部设置了一个组件,让这个组件能够直接把Player找到,从而减少FInd的方式所带来的高负载
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("Not enough money");
return false;
}
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;
}
}