Unity的C#编程教程_59_字典 Dictionary 详解及应用练习

2023-11-17

C# Dictionary: Introduction

  • 字典
    • key 和 value 的配对

依然使用 Item 脚本作为案例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable] // 在 Inspector 中可见
public class Item
{
    public string name;
    public int id;
    public Sprite icon;

}

建立 ItemDatabase 挂载到 Main Camera 上面:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemDatabase : MonoBehaviour
{
    public List<Item> itemList; // 创建一个物品的列表

    public Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>(); // 创建一个物品的字典并初始化(初始化是必须的)
    // key 的类型为 int,value 的类型为 Item
    // key 和 value 形成配对

    // Start is called before the first frame update
    void Start()
    {
        Item sword = new Item(); // 初始化一个物品
        sword.name = "Sword"; // 设定物品的名字
        sword.id = 0; // 设定物品的 id

        itemList.Add(sword); // 为物品列表添加一个元素
        itemDictionary.Add(sword.id, sword); // 为物品字典添加一个元素

        // 使用列表的时候,我们需要通过遍历整个列表来查找某个元素
        // 使用字典的时候,我们可以通过物品的 id 直接查找到对应的元素

        var item = itemDictionary[sword.id];
        Debug.Log(item.name); // 通过 sword 的 id 就可以查找到对应物品
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

C# Dictionary: Looping through Dictionary

  • 循环遍历字典元素

建立 Item:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable] // 在 Inspector 中可见
public class Item
{
    public string name;
    public int id;
    public Sprite icon;
}

建立 ItemDatabase:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemDatabase : MonoBehaviour
{
    public Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
    // 创建一个物品的字典并初始化(初始化是必须的)

    // Start is called before the first frame update
    void Start()
    {
        Item sword = new Item(); // 初始化一个物品
        sword.name = "Sword"; // 设定物品的名字
        sword.id = 0; // 设定物品的 id

        Item axe = new Item();
        axe.name = "Axe";
        axe.id = 1;

        Item bike = new Item();
        bike.name = "Bike";
        bike.id = 2;

        itemDictionary.Add(sword.id, sword); // 为物品字典添加一个元素
        itemDictionary.Add(axe.id, axe);
        itemDictionary.Add(bike.id, bike);

        // 遍历字典:
        foreach(KeyValuePair<int,Item> item in itemDictionary)
        {
            Debug.Log("Key: " + item.Key);
            Debug.Log("Value: " + item.Value.name);
        }
        // 这里我们也可以写成 foreach(var item in itemDictionary)

        // 遍历字典的 key:
        foreach(var key in itemDictionary.Keys)
        {
            Debug.Log("Key: " + key);
        }
        // 这里的 key 是 int 类型
        // 所以也可以写成 foreach(int key in itemDictionary.Keys)

        // 遍历字典的 value:
        foreach (var value in itemDictionary.Values)
        {
            Debug.Log("Item Name: " + value.name);
        }

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

注意:字典中,key 值是不能有重复的,value 可以重复。

另外,在字典中查找的时候,输入的 key 必须存在,否则会报错,为了避免这种情况,可以在前面插入一个检查的程序:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemDatabase : MonoBehaviour
{
    public Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
    // 创建一个物品的字典并初始化(初始化是必须的)

    // Start is called before the first frame update
    void Start()
    {
        Item sword = new Item(); // 初始化一个物品
        sword.name = "Sword"; // 设定物品的名字
        sword.id = 0; // 设定物品的 id

        Item axe = new Item();
        axe.name = "Axe";
        axe.id = 1;

        Item bike = new Item();
        bike.name = "Bike";
        bike.id = 2;

        itemDictionary.Add(sword.id, sword); // 为物品字典添加一个元素
        itemDictionary.Add(axe.id, axe);
        itemDictionary.Add(bike.id, bike);

        if (itemDictionary.ContainsKey(60)) // 检测 60 号物品是否存在
        {
            Debug.Log(itemDictionary[60].name); // 存在的话打印名字
        }
        else
        {
            Debug.Log("Key does not exist."); // 否则打印不存在
        }

        if (itemDictionary.ContainsKey(1)) // 检测 1 号物品是否存在
        {
            Debug.Log(itemDictionary[1].name); // 存在的话打印名字
        }
        else
        {
            Debug.Log("Key does not exist."); // 否则打印不存在
        }

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

C# Dictionary: When to Use

  • 什么时候使用字典
    • 当我们在操作大型的列表时候,该用字典会更为便利
    • 比如我们的道具系统,玩家购买道具的时候,发出指令(输入对应的物品 id)
    • 如果使用列表,我们需要遍历整个列表来查找该物品,而使用字典的话可以直接通过 key 和 value 配对找到
    • 另外比如我们的物品栏,每个空格对应一个 key,然后可以链接不同的物品(即 value)

C# Dictionary: Using Dictionary for Player Connections

  • 在线玩家监测系统
    • 每个玩家登陆游戏的时候分配一个 id
    • 使用字典把 id 和玩家进行配对组合
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player
{
    public string name;
    public int id;

    public Player(int id) // 构造函数,id是必须的属性
    {
        this.id = id;
    }
}


public class Main : MonoBehaviour
{
    public Dictionary<int, Player> playersDict = new Dictionary<int, Player>();
    // 设定一个登陆玩家的字典,并初始化

    Player p1;
    Player p2;

    // Start is called before the first frame update
    void Start()
    {
        p1 = new Player(21); // 登陆一个玩家,分配一个 id
        p1.name = "AA";

        p2 = new Player(34);
        p2.name = "BB";

        playersDict.Add(p1.id, p1); // 把登陆的玩家添加到玩家字典
        playersDict.Add(p2.id, p2);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) // 按下空格键
        {
            if (playersDict.ContainsKey(34)) // 查询玩家 id 是否存在
            {
                Debug.Log("Player Name: " + playersDict[34].name); // 存在的话打印该玩家名字
            }
            else
            {
                Debug.Log("ID not exist!"); // 玩家 id 不存在
            }
        }
    }
}

运行后,会打印 p2 的名字。

C# Dictionary: Using Dictionary with Primitive Types

  • 在字典中使用一些预设的类型,比如 int 和 string

设定一个字典,组成名字和年龄的配对:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Main : MonoBehaviour
{
    public Dictionary<string, int> player = new Dictionary<string, int>();
    // 建立一个字典,并初始化,key 为玩家名字,value 为玩家年龄

    // Start is called before the first frame update
    void Start()
    {
        player.Add("AA", 20); // 添加玩家
        player.Add("BB", 21);
        player.Add("CC", 34);

        int age = player["BB"]; // 获得第二个玩家的年龄

        Debug.Log("The age of BB is " + age); // 显示年龄
    }

    // Update is called once per frame
    void Update()
    {

    }
}

注意:字典只可以通过 key 来查找 value,而不能反过来。

再设计一个 book 的字典:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Main : MonoBehaviour
{
    public Dictionary<int, string> book = new Dictionary<int, string>();
    // 建立一个字典,并初始化,key 为玩家名字,value 为玩家年龄

    // Start is called before the first frame update
    void Start()
    {
        book.Add(123, "Good to go"); // 添加书本
        book.Add(22, "What is that");
        book.Add(25, "How to sell");

        foreach(KeyValuePair<int,string> item in book) // 打印所有书目
        {
            Debug.Log("ID: " + item.Key + " Book: " + item.Value);
        }

    }

    // Update is called once per frame
    void Update()
    {

    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity的C#编程教程_59_字典 Dictionary 详解及应用练习 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐

  • C++学习(四六九)LRU Least Recently Used算法

    LRU是Least Recently Used的缩写 即最近最少使用 最近一段时间最少使用 是一种常用的页面置换算法 选择最近最久未使用的页面予以淘汰 该算法赋予每个页面一个访问字段 用来记录一个页面自上次被访问以来所经历的时间 t 当须淘
  • python解释器多版本安装

    文章目录 1 python解释器的安装 2 配置环境变量 3 在cmd窗口使用python多版本 1 python解释器的安装 要想让计算机能够识别并运行高级语言 要对应类型的翻译官 python这种编程语言的翻译官就是python解释器
  • 网页设计手绘板绘画板,适合初学者学习使用,HTML

    作品如下动态图 下载链接在文末 点我免费下载资源 资源下载链接 https download csdn net download weixin 43474701 34854658
  • Linux系统管理

    磁盘管理 磁盘基本概述 Linux中磁盘的命名方式与磁盘的接口有关 规则如下 传统IDE接口硬盘 dev hd a z SCISI接口硬盘 dev sd a z 虚拟化硬盘 dev vd a z 在设备名称的定义规则如下 其他分区可以以此类
  • MongoDB安装(win)Redis安装

    下载MongoDB 全MonogoDB链接 win安装 进入e盘 找到安装好的文件路径 以E 盘为例 在bin目录同级下创建一个文件夹 data 在data里面创建一个db和logs文件夹 进入logs创建一个文本文档 monogo log
  • 为分布式做准备吧——深入理解JVM

    文章目录 类加载机制 类执行机制 字节码解释执行 运行时 编译执行 反射执行 内存回收 内存空间 收集器 Sun JDK可用的GC 之前我们文章提到过 反射 说的比较浅显 我们这里来理解JVM 一个标准的JVM是这样的 JVM负责装载cla
  • 关于 剪映电脑版无法打开的问题!

    剪映专业版 安装到电脑上使用几次后 突然就打不开了 经过几天的漫长查找网上也无一个答案 说什么字体冲突的 都不是病根 这个bug病根是业务层加载不到veCreator dll 代码里尝试去加载veCreator dll dll 导致异常 下
  • 使用OSWatcher来监控服务器

    OSWatcher是oracle提供的监控服务器资源的工具 配合AWR等工具为调优数据库提供基本信息 OSWatcher有支持不同平台 WINDOWS平台下 OSWatcher For Windows OSWFW LINUX平台 OS Wa
  • RGMII信号是什么样子的----大揭秘

    RGMII信号 测试 1 测试RGMII 先判断RGMII信号频率多少 就知道是千兆百兆的模式 发送时钟信号 速率为Gbit s时 时钟速率为125MHz 速率为100Mbit s时 速率为25MHz 速率为10Mbit s时 速率为2 5
  • java自动化测试语言基础之方法

    java自动化测试语言基础之方法 文章目录 java自动化测试语言基础之方法 Java 方法 Java 方法 在前面几个章节中我们经常使用到 System out println 那么它是什么呢 println 是一个方法 System 是
  • Linux网络通信----htonl()、htons()、ntohl()、ntohs()四个函数

    转载 https blog csdn net miao19920101 article details 69398158 前言 今天在工作中用到htonl 这个函数 不是很理解 查阅资料之后随笔就记录下来 方便以后工作和学习翻阅 首先需要说
  • python反复运行清空plot图_仅清除matplotlib图的一部分

    我正在使用嵌入在Wx Python GUI中的matplotlib图来呈现一些数据 图中的内容 显示的数据 随点击按钮的功能不断变化 数据有两种类型 1 轮廓线 self axes contour x scale map y scale m
  • 并发锁的学习

    锁 锁的定义 锁是用来协调多个线程并发访问同一共享资源时带来的安全问题 频繁用锁必然会带来性能问题 但不用锁又会造成安全问题 1 从性能上分 乐观锁和悲观锁 乐观锁 CAS自旋锁 是非常经典的乐观锁 并发性能比较好 但是自旋会造成很大的开销
  • Python经典练习题——求水仙花数

    严格来说 我并不知道何谓 水仙花数 因为以前读书时根本没听过这种数 也不知道这种数有什么特征 后来从事编程之后反而听说了所谓的 水仙花数 如果通过网络查询 则发现水仙花数的定义也不统一 比如通过baidu百科查到如下定义 水仙花数 Narc
  • 元数据管理工具atlas初探

    元数据管理工具atlas初探 安装 Ambari添加服务 略 Hive配置 将atlas主节点 usr hdp 2 6 3 0 235 atlas hook拷贝到其他节点 自定义hive env HIVE AUX JARS PATH usr
  • 携手区块链技术,踏上可信“双碳”之路

    自中央明确提出碳达峰碳中和的 双碳 目标以来 区块链技术凭借能为碳排放 碳足迹打上可信标签的天赋异禀 引起了政策部门 学术界及产业实践代表们的高度重视 7月11日 在第33个全国节能宣传周之际 全国低碳日前夕 微众区块链联合金链盟 FISC
  • gcc生成静态库与动态库(附带使用方法)

    目录 前言 1 gcc生成静态库 从使用者的角度出发 如何使用别人的静态库 方法1 方法2 直接使用静态库 2 gcc生成动态库 动态库的使用 第二种方法 与使用静态库的方法一样 解决方案 方法3 ldconfig 配置 etc ld so
  • json解析豆瓣数据

    继续上次的文章 我们找到了json的数据包 那么证明我们可以获取到他们的数据 点击Headers Request URL对应的就是json数据的url 找到url之后我们就可以开始爬虫了 import requests import jso
  • Windows和Linux混合系统通过AD域实现用户集中认证

    一 Windows AD域 1 统一认证简介 管理的Linux服务器和Windows服务器如果很多 如果都用本地用户名管理 要管理和记住几十台甚至上百台服务器的不同账号不同密码 这是很难的 但是如果所有服务器账号密码都设置一样 那又完全没有
  • Unity的C#编程教程_59_字典 Dictionary 详解及应用练习

    文章目录 C Dictionary Introduction C Dictionary Looping through Dictionary C Dictionary When to Use C Dictionary Using Dicti