news 2026/6/10 11:00:33

UGUI 读取JSON动态克隆背包道具信息

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UGUI 读取JSON动态克隆背包道具信息

Unity背包系统 - JSON读取完整实现

一、Excel转JSON方法

1.1 Excel表格格式示例

创建Items.xlsx,结构如下:

ItemNameItemImageNameItemCountItemNumberItemType
生命药水HealthPotion510011
魔力药水ManaPotion310021
长剑Sword120012

1.2 将Excel转为JSON的方法

方法一:使用在线转换工具

  1. 将Excel另存为CSV格式

  2. 使用CSV转JSON在线工具

  3. 保存为Items.json,放到Unity的Resources文件夹中

方法二:使用C#脚本转换
创建ExcelToJsonConverter.cs

using UnityEngine; using System.IO; #if UNITY_EDITOR using Excel = Microsoft.Office.Interop.Excel; #endif public class ExcelToJsonConverter : MonoBehaviour { #if UNITY_EDITOR [ContextMenu("Convert Excel to JSON")] public void ConvertExcelToJson() { string excelPath = Application.dataPath + "/Items.xlsx"; string jsonPath = Application.dataPath + "/Resources/Items.json"; Excel.Application excelApp = new Excel.Application(); Excel.Workbook workbook = excelApp.Workbooks.Open(excelPath); Excel.Worksheet worksheet = workbook.Sheets[1]; // 读取数据转换为JSON // ... 转换代码 ... workbook.Close(); excelApp.Quit(); } #endif }

二、完整的JSON读取实现

2.1 JSON数据结构类

// ItemData.cs - JSON数据类 using System; using System.Collections.Generic; [Serializable] public class ItemList { public List<ItemJsonData> items; } [Serializable] public class ItemJsonData { public string itemName; public string imageName; // 图片文件名 public int itemCount; public int itemNumber; public int itemType; }

2.2 道具信息类(优化版)

// itemonfro.cs - 道具信息类 using UnityEngine; [System.Serializable] public class itemonfro { public string Itemname; public Sprite ItemImage; public int ItemCount; public int ItemNumBu; public int ItemType; // 空构造函数供JSON解析使用 public itemonfro() { } // 构造函数 public itemonfro(string name, Sprite image, int count = 1, int id = 0, int type = 0) { Itemname = name; ItemImage = image; ItemCount = count; ItemNumBu = id; ItemType = type; } }

2.3 完整的ItemClone类

using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class ItemClone : MonoBehaviour { [Header("UI组件")] public GameObject ItemGridPre; // 道具格子预制体 public RectTransform ItemGridParent; // Content父物体 [Header("资源管理")] public List<Sprite> ItemImageInfro; // 所有道具图片列表 public string jsonFilePath = "Items"; // JSON文件路径(不带后缀) [Header("道具数据")] public itemonfro[] ItemAllInfo; // 道具信息数组 // 图片名称映射字典 private Dictionary<string, Sprite> spriteDictionary = new Dictionary<string, Sprite>(); private void Awake() { // 1. 初始化图片字典 InitializeSpriteDictionary(); // 2. 从JSON加载数据 LoadDataFromJSON(); // 3. 克隆道具格子 CloneItem(); } // 初始化图片字典 void InitializeSpriteDictionary() { spriteDictionary.Clear(); foreach (Sprite sprite in ItemImageInfro) { if (sprite != null && !spriteDictionary.ContainsKey(sprite.name)) { spriteDictionary.Add(sprite.name, sprite); } } } // 从JSON文件加载数据 void LoadDataFromJSON() { // 1. 加载JSON文件 TextAsset jsonFile = Resources.Load<TextAsset>(jsonFilePath); if (jsonFile == null) { Debug.LogError($"找不到JSON文件: {jsonFilePath}"); CreateDefaultItems(); return; } try { // 2. 解析JSON数据 ItemList itemList = JsonUtility.FromJson<ItemList>(jsonFile.text); if (itemList == null || itemList.items == null) { Debug.LogError("JSON解析失败,使用默认数据"); CreateDefaultItems(); return; } // 3. 创建itemonfro数组 ItemAllInfo = new itemonfro[itemList.items.Count]; for (int i = 0; i < itemList.items.Count; i++) { ItemJsonData jsonData = itemList.items[i]; // 创建新的itemonfro对象 ItemAllInfo[i] = new itemonfro(); // 赋值数据 ItemAllInfo[i].Itemname = jsonData.itemName; ItemAllInfo[i].ItemCount = jsonData.itemCount; ItemAllInfo[i].ItemNumBu = jsonData.itemNumber; ItemAllInfo[i].ItemType = jsonData.itemType; // 通过图片名称查找Sprite if (!string.IsNullOrEmpty(jsonData.imageName)) { if (spriteDictionary.ContainsKey(jsonData.imageName)) { ItemAllInfo[i].ItemImage = spriteDictionary[jsonData.imageName]; } else { Debug.LogWarning($"找不到图片: {jsonData.imageName},使用默认图片"); ItemAllInfo[i].ItemImage = GetDefaultSprite(); } } else { ItemAllInfo[i].ItemImage = GetDefaultSprite(); } } Debug.Log($"成功加载 {ItemAllInfo.Length} 个道具"); } catch (System.Exception e) { Debug.LogError($"JSON解析错误: {e.Message}"); CreateDefaultItems(); } } // 获取默认Sprite Sprite GetDefaultSprite() { if (ItemImageInfro != null && ItemImageInfro.Count > 0) return ItemImageInfro[0]; return null; } // 创建默认道具数据(JSON加载失败时使用) void CreateDefaultItems() { ItemAllInfo = new itemonfro[5]; ItemAllInfo[0] = new itemonfro("生命药水", GetDefaultSprite(), 5, 1001, 1); ItemAllInfo[1] = new itemonfro("魔力药水", GetDefaultSprite(), 3, 1002, 1); ItemAllInfo[2] = new itemonfro("长剑", GetDefaultSprite(), 1, 2001, 2); ItemAllInfo[3] = new itemonfro("盾牌", GetDefaultSprite(), 1, 2002, 2); ItemAllInfo[4] = new itemonfro("金币", GetDefaultSprite(), 999, 3001, 3); } // 克隆道具到UI void CloneItem() { if (ItemAllInfo == null || ItemAllInfo.Length == 0) { Debug.LogError("没有道具数据可显示"); return; } // 清空现有道具格子 foreach (Transform child in ItemGridParent) { Destroy(child.gameObject); } // 克隆新道具格子 for (int i = 0; i < ItemAllInfo.Length && i < 100; i++) // 限制最多100个 { // 实例化预制体 GameObject TempItemGrid = Instantiate(ItemGridPre, ItemGridParent); TempItemGrid.name = $"Item_{ItemAllInfo[i].Itemname}_{i}"; try { // 获取UI组件并赋值 TextMeshProUGUI nameText = TempItemGrid.transform .GetChild(2) // 假设第3个子物体是名称容器 .GetChild(0) .GetChild(0) .GetComponent<TextMeshProUGUI>(); Image itemImage = TempItemGrid.transform .GetChild(3) // 假设第4个子物体是图片 .GetComponent<Image>(); // 赋值数据 if (nameText != null) nameText.text = ItemAllInfo[i].Itemname; if (itemImage != null && ItemAllInfo[i].ItemImage != null) itemImage.sprite = ItemAllInfo[i].ItemImage; // 设置计数显示(可选) Transform countTransform = TempItemGrid.transform.Find("ItemCount"); if (countTransform != null) { TextMeshProUGUI countText = countTransform.GetComponent<TextMeshProUGUI>(); if (countText != null) { countText.text = ItemAllInfo[i].ItemCount > 1 ? ItemAllInfo[i].ItemCount.ToString() : ""; } } } catch (System.Exception e) { Debug.LogError($"设置道具 {i} 时出错: {e.Message}"); } } } // 重新加载数据(可在编辑器测试用) [ContextMenu("重新加载JSON数据")] void ReloadData() { LoadDataFromJSON(); CloneItem(); } }

三、JSON文件示例

{ "items": [ { "itemName": "生命药水", "imageName": "HealthPotion", "itemCount": 5, "itemNumber": 1001, "itemType": 1 }, { "itemName": "魔力药水", "imageName": "ManaPotion", "itemCount": 3, "itemNumber": 1002, "itemType": 1 }, { "itemName": "长剑", "imageName": "Sword", "itemCount": 1, "itemNumber": 2001, "itemType": 2 }, { "itemName": "盾牌", "imageName": "Shield", "itemCount": 1, "itemNumber": 2002, "itemType": 2 }, { "itemName": "钥匙", "imageName": "Key", "itemCount": 3, "itemNumber": 3001, "itemType": 3 } ] }

、使用步骤

  1. 准备图片资源

    • 将道具图片导入Unity

    • 图片命名与JSON中的imageName一致

    • 将所有图片拖到ItemImageInfro列表中

  2. 创建JSON文件

    • Assets/Resources文件夹中创建Items.json

    • 按格式编写道具数据

  3. 设置UI组件

    • 将预制体和Content拖到对应位置

    • 确保预制体结构与代码中的GetChild索引匹配

  4. 运行测试

    • 运行游戏即可看到从JSON加载的道具

    • 修改JSON文件后,可在编辑器中使用"重新加载JSON数据"菜单更新

五、注意事项

  1. 图片查找:确保JSON中的imageName与导入的Sprite名称完全一致

  2. JSON格式:必须严格按照JSON格式,可使用JSON验证工具

  3. 路径问题:JSON文件必须放在Resources文件夹内

  4. 预制体结构:确保预制体结构与代码中的GetChild索引匹配

这样就完成了从Excel到JSON再到Unity背包的完整流程!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 13:33:36

Golang 高并发秒杀系统踩坑

秒杀场景的核心痛点是瞬时高并发&#xff08;QPS 数万/数十万&#xff09;、库存超卖、接口防刷、性能瓶颈等&#xff0c;Go 虽天生适合高并发&#xff0c;但落地秒杀系统时仍易踩诸多坑。本文梳理高频踩坑点、根因及解决方案&#xff0c;覆盖业务、架构、代码层面。 一、核心坑…

作者头像 李华
网站建设 2026/6/10 11:39:17

三维设计软件 | CATIA 2022百度云盘中文正式版下载教程

如大家所熟悉的&#xff0c;CATIA是一款功能强大且应用较为广泛的三维计算机辅助设计/辅助制造&#xff08;CAD/CAE/CAM&#xff09;软件系统。它流行于航空航天、汽车制造、船舶制造、机械制造、电子/电器、消费品等行业&#xff0c;提供从产品设计、分析、模拟到组装的集成解…

作者头像 李华
网站建设 2026/6/10 15:07:36

测试中的数据分析与决策

1 测试数据的潜在价值与挑战在敏捷开发与DevOps实践日益普及的2025年&#xff0c;软件测试已从单纯的质量保障环节转变为产品决策的关键数据来源。测试过程中产生的海量数据——包括自动化测试执行结果、性能基准指标、缺陷分布模式、用户行为轨迹以及环境配置参数等——构成了…

作者头像 李华
网站建设 2026/6/10 11:55:00

Linux内核实时调度深度剖析:从设计哲学到实战应用

在当今嵌入式系统和工业控制领域&#xff0c;实时性已成为系统可靠性的生命线。Linux内核通过其精心设计的实时调度策略&#xff0c;为苛刻的时间约束应用提供了坚实的底层支撑。本文将带您深入探索SCHED_FIFO与SCHED_RR两种核心调度机制的设计理念、实现细节及实际应用模式。 …

作者头像 李华