当前位置: 首页 > news >正文

【在Unity游戏开发中Dictionary、List介绍】

在Unity游戏开发中,DictionaryList是最核心的两种数据结构,它们各自有优势和应用场景。以下是介绍:


🧠 数据结构本质对比

特性Dictionary<TKey, TValue>List
底层结构哈希表(Hash Table)动态数组(Dynamic Array)
查找效率O(1) 按键查找O(n) 遍历查找
插入/删除效率O(1) ~ O(n) (哈希冲突时)O(n) (需移位)
内存占用较高(存储哈希桶和指针)较低(连续内存)
数据顺序无序严格顺序
核心优势键值配对 + 高速查找顺序访问 + 随机索引

各自擅长领域

**Dictionary **
// 典型案例:用ID快速定位游戏对象
Dictionary<int, Enemy> _enemyDict = new Dictionary<int, Enemy>();void SpawnEnemy(int id) {Enemy prefab = Resources.Load<Enemy>($"Enemies/{id}");Enemy enemy = Instantiate(prefab);_enemyDict.Add(id, enemy); // O(1)插入
}Enemy GetEnemy(int id) {return _enemyDict.TryGetValue(id, out Enemy e) ? e : null; // O(1)查找
}

适用场景:
✅ 通过唯一ID查找对象(玩家/敌人/NPC)
✅ 建立资源路径与实例映射(如:“Weapons/Sword” → 预制体)
✅ 实时数据索引(成就ID → 完成状态)
✅ 避免重复添加(用ContainsKey检查存在性)

📜 **List **
// 典型案例:游戏对象批量处理
List<Bullet> _activeBullets = new List<Bullet>();void UpdateBullets() {for(int i = 0; i < _activeBullets.Count; ) {if(_activeBullets[i].IsExpired) {_activeBullets.RemoveAt(i); // 移除时需小心索引变化} else {_activeBullets[i++].Update();}}
}// 添加新子弹
void FireBullet() {Bullet b = _bulletPool.Get();_activeBullets.Add(b); // O(1)尾部添加
}

适用场景:
✅ 需要严格顺序的数据(对话文本序列)
✅ 需高频遍历的集合(每帧更新所有子弹)
✅ 动态增减的集合(背包物品、技能冷却队列)
✅ 需要排序操作的场景(玩家积分排行榜)


经典组合应用

1. 背包系统(高性能实现)
Dictionary<int, ItemData> _itemDB; // 静态数据表:ID->属性
Dictionary<int, ItemInstance> _inventoryDict; // 库存实例:ID->实例
List<ItemInstance> _inventoryList; // 显示用有序列表void AddItem(int itemId, int count) {// 1. 从字典快速检查存在性if(_inventoryDict.TryGetValue(itemId, out ItemInstance instance)) {instance.count += count; // 堆叠} else {// 2. 创建新实例ItemData data = _itemDB[itemId]; // 从静态字典取数据instance = new ItemInstance(data, count);// 3. 同步双结构_inventoryDict.Add(itemId, instance);_inventoryList.Add(instance); }// 4. 列表排序(List专长)_inventoryList.Sort(SortByRarity); 
}// 排序逻辑(List专属操作)
int SortByRarity(ItemInstance a, ItemInstance b) {return b.data.rarity.CompareTo(a.data.rarity);
}
⚡️ 2. 对象池系统(高效复用)
Dictionary<GameObject, List<GameObject>> _pool = new Dictionary<GameObject, List<GameObject>>();GameObject Spawn(GameObject prefab) {// 1. 字典查找对应对象池if(!_pool.TryGetValue(prefab, out List<GameObject> list)) {list = new List<GameObject>();_pool.Add(prefab, list);}// 2. 列表查找可用对象foreach(GameObject obj in list) {if(!obj.activeInHierarchy) return obj;}// 3. 列表无可用则创建新对象GameObject newObj = Instantiate(prefab);list.Add(newObj); // 加入Listreturn newObj;
}
🛡️ 3. 技能管理系统
Dictionary<string, SkillData> _skillDB; // ID->技能配置
List<ActiveSkill> _activeSkills; // 激活中技能列表void CastSkill(string skillId) {// 1. 从字典读取基础数据(O(1))SkillData data = _skillDB[skillId];// 2. 创建技能实例ActiveSkill skill = new ActiveSkill(data);// 3. 加入List进行更新_activeSkills.Add(skill);
}void Update() {// 4. 遍历List更新技能(顺序重要!)for(int i=0; i<_activeSkills.Count; i++) {_activeSkills[i].Update();}
}

⚠️ 避坑指南

  1. 字典遍历陷阱

    // 错误!修改集合时不能遍历
    foreach(var key in _dict.Keys) {if(condition) _dict.Remove(key); // 抛出InvalidOperationException
    }// 正确做法
    List<TKey> keysToRemove = new List<TKey>();
    foreach(var key in _dict.Keys) {if(condition) keysToRemove.Add(key);
    }
    foreach(var key in keysToRemove) {_dict.Remove(key);
    }
    
  2. 列表删除优化

    // 正序删除导致索引错乱
    for(int i=0; i<list.Count; i++) {if(condition) list.RemoveAt(i--); // 需手动调整索引
    }// 倒序删除更安全
    for(int i=list.Count-1; i>=0; i--) {if(condition) list.RemoveAt(i);
    }
    
  3. 空值防御

    // 字典安全访问
    if(_dict.TryGetValue(key, out var value)) {// 安全操作value
    }// 列表边界检查
    if(index >= 0 && index < list.Count) {var item = list[index];
    }
    

如何选择 请添加图片描述

!:

  1. 频繁查找 + 无序数据 → Dictionary
  2. 顺序访问/修改 → List
  3. 需要两者特性 → Dictionary与List联动

在Unity 2023+版本中,可考虑HashSet(无值字典)或LinkedList(高效增删),但Dictionary+List组合仍是90%游戏系统的首选,尤其在需要高性能查询和灵活排序的场景中。

http://www.dtcms.com/a/300839.html

相关文章:

  • 基于Springboot+UniApp+Ai实现模拟面试小工具七:前端项目创建及框架搭建
  • 深入理解 Spring 中的 XmlBeanFactory 原理及实践
  • 【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程
  • ArKTS:List 数组
  • 机器学习特征选择 explanation and illustration of ANOVA
  • ROS2总结(二)
  • UDS 0x29 身份验证服务 Authentication service
  • Rust Web 全栈开发(十一):WebAssembly 尝鲜
  • 2507rust,rust写驱动
  • rust- 定义模块以控制作用域和隐私
  • 无刷电机三项霍尔连接线序组合详细分析与波形实例
  • ETF历史每笔成交分钟级高频数据深度解析
  • 墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)
  • Rust与Java DynamoDB、MySQL CRM、tokio-pg、SVM、Custors实战指南
  • 零基础 “入坑” Java--- 十四、字符串String
  • mybatis-plus实体类主键生成策略
  • 使用uni-app开发一个点餐收银台系统前端静态项目练习
  • 车辆网络安全规定之R155与ISO/SAE 21434
  • 09_opencv_遍历操作图像像素
  • uniapp input 聚焦时键盘弹起滚动到对应的部分
  • 基础配置介绍,VLAN配置,DHCP配置
  • 迷宫生成与路径搜索(A算法可视化)
  • SparkSQL — get_json_object函数详解(解析 json)
  • 离散组合数学 : 母函数
  • QT6 源,七章对话框与多窗体(16)多文档 MDI 窗体 QMdiArea 篇二:源代码带注释
  • 栈----4.每日温度
  • AIC 2025 热点解读:如何构建 AI 时代的“视频神经中枢”?
  • 主要分布于内侧内嗅皮层的层Ⅲ的边界向量细胞(BVCs)对NLP中的深层语义分析的积极影响和启示
  • Tkinter美化 - 告别土味Python GUI
  • VScode输出中文乱码问题解决