效果演示
文章目录
- 效果演示
- 系列目录
- 前言
- 存储加载物品信息
- 源码
- 完结
系列目录
前言
欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中,我们将探索如何用unity制作一个3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱等功能,我会附带项目源码,以便你更好理解它。
存储加载物品信息
新增SaveInventory,保存和加载物品数据
public class SaveInventory : Singleton<SaveInventory>
{
[Header("保存加载")]
public List<GameObject> allItemPrefabs = new List<GameObject>(); //物品预制体列表
private string saveFileName = "inventorySave.json";
//开始加载数据
private void Start()
{
loadInventory();
}
//退出保存数据
private void OnApplicationQuit()
{
saveInventory();
}
// 保存物品数据
private void saveInventory()
{
List<Slot> allInventorySlots = Inventory.Instance.allInventorySlots;
InventoryData data = new InventoryData();
foreach (Slot slot in allInventorySlots) // 遍历所有插槽
{
Item item = slot.getItem(); // 获取插槽中的物品
if (item != null)
{
ItemData itemData = new ItemData(item.name, item.currentQuantity, allInventorySlots.IndexOf(slot)); // 创建物品数据
data.slotData.Add(itemData); // 添加至插槽数据列表
}
}
string jsonData = JsonUtility.ToJson(data); // 序列化为 JSON 格式
File.WriteAllText(saveFileName, jsonData); // 将数据写入文件
}
// 加载物品数据
public void loadInventory()
{
List<Slot> allInventorySlots = Inventory.Instance.allInventorySlots;
if (File.Exists(saveFileName))
{
string jsonData = File.ReadAllText(saveFileName); // 从文件中读取数据
InventoryData data = JsonUtility.FromJson<InventoryData>(jsonData); // 反序列化为 InventoryData 对象
Inventory.Instance.clearInventory(); // 清空物品
foreach (ItemData itemData in data.slotData) // 遍历插槽数据列表
{
GameObject itemPrefab = allItemPrefabs.Find(prefab => prefab.GetComponent<Item>().name == itemData.itemName); // 根据物品名称查找对应的预制体
if (itemPrefab != null)
{
GameObject createdItem = Instantiate(itemPrefab, Inventory.Instance.dropLocation.position, Quaternion.identity); // 在指定位置创建物品
Item item = createdItem.GetComponent<Item>();
item.currentQuantity = itemData.quantity; // 设置物品数量
Inventory.Instance.addItemToInventory(item, itemData.slotIndex); // 将物品添加到相应插槽中
}
}
}
foreach (Slot slot in allInventorySlots) // 更新所有插槽的数据
{
slot.updateData();
}
}
}
[System.Serializable]
public class ItemData
{
public string itemName; // 物品名称
public int quantity; // 数量
public int slotIndex; // 插槽索引
public ItemData(string itemName, int quantity, int slotIndex)
{
this.itemName = itemName;
this.quantity = quantity;
this.slotIndex = slotIndex;
}
}
[System.Serializable]
public class InventoryData
{
public List<ItemData> slotData = new List<ItemData>(); // 插槽数据列表
}
修改Inventory
//将物品添加到背包中
public void addItemToInventory(Item itemToAdd, int overrideIndex = -1)
{
//如果指定了覆盖索引,则将物品添加到指定的槽位中
if(overrideIndex != -1 && overrideIndex < allInventorySlots.Count){
allInventorySlots[overrideIndex].setItem(itemToAdd);
itemToAdd.gameObject.SetActive(false);
allInventorySlots[overrideIndex].updateData();
return;
}
//。。。
}
// 清空物品
public void clearInventory()
{
foreach (Slot slot in allInventorySlots)
{
slot.setItem(null);
}
}
注意
:记得修改Inventory的Start方法为Awake或者OnEnable,确保Inventory初始化在SaveInventory的Start之前执行,不然会出错,对unity生命周期函数还不了解的小伙伴可以看我这篇文章:【2023Unity游戏开发教程】零基础带你从小白到超神05——脚本组件和生命周期函数
挂载配置参数
效果
先进入拾取物品,放在随机位置,退出游戏
查看保存的文件信息,在项目目录下
再次进入游戏,查看之前的物品被成功加载了
源码
源码不出意外的话我会放在最后一节
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~