Unity的C#編程教程_59_字典 Dictionary 詳解及應用練習
目錄:
C# Dictionary: Introduction
C# Dictionary: Looping through Dictionary
C# Dictionary: When to Use
C# Dictionary: Using Dictionary for Player Connections
C# Dictionary: Using Dictionary with Primitive Types
C# Dictionary: Looping through Dictionary
C# Dictionary: When to Use
C# Dictionary: Using Dictionary for Player Connections
C# Dictionary: Using Dictionary with Primitive Types
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()
{
}
}