学习游戏制作记录(保存装备物品技能树和删除存档文件)8.26

1.保存库存物品

创建SerializbleDictionary脚本:

System.Serializable
public class SerializbleDictionary<Tkey, TValue> : Dictionary<Tkey, TValue>, ISerializationCallbackReceiver//手动实现字典序列化
{
SerializeField private List<Tkey> keys = new List<Tkey>();
SerializeField private List<TValue> values = new List<TValue>();
public void OnBeforeSerialize()
{

keys.Clear();
values.Clear();

foreach (KeyValuePair<Tkey, TValue> pairs in this)
{
keys.Add(pairs.Key);
values.Add(pairs.Value);
}
}

public void OnAfterDeserialize()
{
this.Clear();

if (keys.Count != values.Count)
{
Debug.Log("Not Equie");
}

for (int i = 0; i < keys.Count; i++)
{
this.Add(keysi, valuesi);
}
}

}

GameData脚本:

public SerializbleDictionary<string, int> Inventory;//使用字典序列

public GameData()
{
this.currency = 0;

Inventory =new SerializbleDictionary<string, int>();
}

Inventory脚本:

Header("Data Base")
private List<InventoryItem> LoadedItems =new List<InventoryItem>();//待加载的物品

private void AddStartingItem()
{
if(LoadedItems.Count>0)//初始化物品,是否要加载
{
foreach(InventoryItem item in LoadedItems)
{
for(int i = 0;i<item.stackSize;i++)
{
AddItem(item.data);
}
}

return;
}

for (int i = 0; i < startingItem.Count; i++)
{
if(startingItemi != null)
AddItem(startingItemi);
}
}

public void LoadDate(GameData gameData)//加载函数
{
foreach(KeyValuePair<string,int> pair in gameData.Inventory)
{
foreach(var item in GetItemDataBase())在保存的序列里搜索
{
if(item!=null&&item.ItemID==pair.Key)
{
InventoryItem itemToLoad =new InventoryItem(item);

itemToLoad.stackSize = pair.Value;

LoadedItems.Add(itemToLoad);//添加
}
}
}
}

public void SaveDate(ref GameData gameData)
{
gameData.Inventory.Clear();

foreach (KeyValuePair<ItemData, InventoryItem> pair in inventoryItemsDictionary)
{
gameData.Inventory.Add(pair.Key.ItemID, pair.Value.stackSize);//添加到字典序列
}
}

private List<ItemData> GetItemDataBase()//获取保存的序列
{
List<ItemData> itemDatas = new List<ItemData>();
string\[\] assestsName = AssetDatabase.FindAssets("", new\[\] { "Assets/Data/Equipment" });

foreach(string SQName in assestsName)
{
var SQpath =AssetDatabase.GUIDToAssetPath(SQName);
var itemData= AssetDatabase.LoadAssetAtPath<ItemData>(SQpath);

itemDatas.Add(itemData);
}

return itemDatas;
}

2.保存材料和已经装备的物品

GameData脚本:

public List<string> equipmentId;//已装备物品的id

Inventory脚本:

public List<ItemData_Equipment> loadedEquipments;//已装备物品的列表

private void AddStartingItem()
{
foreach(ItemData_Equipment item in loadedEquipments)//初始化已经装备的物品
{
EquipItem(item);
}

if(LoadedItems.Count>0)
{
foreach(InventoryItem item in LoadedItems)
{
for(int i = 0;i<item.stackSize;i++)
{
AddItem(item.data);
}
}

return;
}

for (int i = 0; i < startingItem.Count; i++)
{
if(startingItemi != null)
AddItem(startingItemi);
}
}

public void SaveDate(ref GameData gameData)
{
gameData.Inventory.Clear();
gameData.equipmentId.Clear();

foreach (KeyValuePair<ItemData, InventoryItem> pair in inventoryItemsDictionary)
{
gameData.Inventory.Add(pair.Key.ItemID, pair.Value.stackSize);
}

foreach (KeyValuePair<ItemData,InventoryItem>pair in stashItemsDictionary)//保存材料
{
gameData.Inventory.Add(pair.Key.ItemID,pair.Value.stackSize);
}

foreach(KeyValuePair<ItemData_Equipment,InventoryItem> pair in equipmentDictionary)//保存装备的物品
{
gameData.equipmentId.Add(pair.Key.ItemID);
}
}

public void LoadDate(GameData gameData)
{
foreach(KeyValuePair<string,int> pair in gameData.Inventory)
{
foreach(var item in GetItemDataBase())
{
if(item!=null&&item.ItemID==pair.Key)
{
InventoryItem itemToLoad =new InventoryItem(item);

itemToLoad.stackSize = pair.Value;

LoadedItems.Add(itemToLoad);
}
}
}

foreach(string loadedItemID in gameData.equipmentId)//将已保存的装备添加到列表中
{
foreach(var item in GetItemDataBase())
{
if(item!=null && item.ItemID==loadedItemID)
{
loadedEquipments.Add(item as ItemData_Equipment);
}
}
}
}

3.保存技能树

UI_SkillTreeSlot脚本:

public class UI_SkillTreeSlot : MonoBehaviour,IPointerEnterHandler, IPointerExitHandler,ISaveManager实现ISaveManager接口

public void LoadDate(GameData gameData)
{
if(gameData.skilltree.TryGetValue(skillName,out bool value))//加载bool
unlocked = value;
}

public void SaveDate(ref GameData gameData)
{
if(gameData.skilltree.TryGetValue(skillName,out bool value))
{
gameData.skilltree.Remove(skillName);
gameData.skilltree.Add(skillName, unlocked);
}
else
{
gameData.skilltree.Add(skillName, unlocked);
}
}

Skill脚本:

protected virtual void Start()
{
player = PlayerManage.instance.player;

CheckUnlocked();
}

protected virtual void CheckUnlocked()//每个技能单独重写
{

}

以Blackhole_Skill脚本为例:

protected override void CheckUnlocked()
{

UnlockBlackHole();///调用解锁函数
}

4.删除保存的文档

FileDataHandler 脚本:

public void Delete()
{
string fullPath = Path.Combine(dataDirPath, FileName);

if(File.Exists(fullPath))//检测是否存在
{
File.Delete(fullPath);
}
}

SaveManager脚本:

ContextMenu("Delete save data")//右击脚本可以看到选项直接调用函数
private void DeletSavedData()
{
dataHandler = new FileDataHandler(Application.persistentDataPath, fileName);
dataHandler.Delete();
}

相关推荐
STLearner1 分钟前
ICML 2026 | LLM×Graph论文总结[2]【Graph4LLM,Graph4Agent,智能体记忆(Memory)
大数据·人工智能·python·深度学习·学习·机器学习·数据挖掘
其实防守也摸鱼1 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
android·运维·网络·人工智能·学习·安全·macos
YM52e6 小时前
鸿蒙Flutter Padding内边距:EdgeInsets详解
android·学习·flutter·华为·harmonyos·鸿蒙
爱写代码的阿木7 小时前
基于鸿蒙OS开发附近社交游戏平台(二十二)-ChatPage 即时通讯 UI
游戏·华为·harmonyos
西安老张(AIGC&ComfyUI)8 小时前
第034章:ComfyUI&AIGC一阶段学习总结及下阶段学习安排
学习·aigc
爱写代码的阿木10 小时前
基于鸿蒙OS开发附近社交游戏平台(二十三)-拉黑系统、屏蔽与全局过滤
游戏·华为·harmonyos
正经人_x11 小时前
学习日记43:FINO
学习
吴可可12312 小时前
C#用OpenCVSharp提取轮廓生成CAD多段线
c#
网络工程小王13 小时前
【HCIE-AI】11.模型 昇腾迁移适配-精度调试-性能调优
人工智能·学习·华为·迁移学习·昇腾
一只小菜鸡..14 小时前
CMU 15-213 CSAPP:机器级编程与内存的暗黑魔法(Machine-Level)
笔记·学习