Unity + Arduino:用 RFID 開發實體道具辨識的互動功能

Ted Liou 2025.06.10 實體介面
RFID 是一種感應技術,能有效辨識多個感應標籤之間的差異,開發者可以藉由這個特性來設計實體互動裝置。使用 Unity 開發的互動作品,可以透過 Arduino 來讓作品接收 RFID 讀取器的結果,再根據拿到的 RFID 標籤編號來改變系統的行為,以產生互動回饋。

Unity + Arduino 的組合是一個常見的架構。Unity 是一個遊戲引擎,使用 C# 語言來開發,能有效的使用 Serial Port 來和 Arduino 溝通。而 Arduino 能連接各種電路與晶片,再配合價格低廉的 MFRC522 RFID 讀取器與自行埋在道具之中的 RFID 標籤,就能用很低的成本來開發出實體互動裝置。

參考以下影片,開發者將 RFID 標籤藏在玩具車的下面。當玩具車被放置在 RFID 讀取器上 (紅色框),Unity 就會生成對應玩具車的物件。我們能透過這個觀念,配合實體道具來設計互動系統,能強化使用者對於實體道具和虛擬元素之間的聯想。例如:用滑鼠在遊戲內開槍 vs. 拿實體槍來在遊戲內開槍,這之間的體驗感受就差很多了!

本文將說明如何使用 Unity 與 Arduino 來用 RFID 開發實體道具的互動功能,我們會使用到 MFRC522 晶片MFRC522 支援的感應標籤 (13.56MHz)Arduino Uno 主機板

建立 RFID 讀取功能

Arduino 與 RFID 晶片之間需使用電線來連接,於連接後才能透過電腦上的 Arduino IDE 來燒錄 RFID 程式。

連接 Arduino + RFID

我們使用 MFRC522 晶片來作為 RFID 的讀取器,全新的 MFRC522 晶片會附帶排針,開發者需要自行將排針焊接到晶片上,才能用杜邦公母線來連接。由於 MFRC522 需要連接的線路很多,再加上杜邦線很常出現接觸不良或斷路的問題,建議在連接完畢後拿三用電表來測一下每個線路是否有接通。直接使用杜邦線連接 Arduino Uno 與 MFRC522 後的狀態會長這樣:

Arduino與MFRC522的連接後照片

MFRC522 各個針腳對應到 Arduino Uno 的針腳編號如下表,MFRC522 的針腳名稱有印在接口旁邊,Arduino Uno 的針腳編號皆為數位腳位。

MFRC522 針腳Arduino Uno 針腳
SDA10
SCK13
MOSI11
MISO12
IRQ不用連接
GNDGND
RST9
3.3V3.3V

連接後的電路圖如下,請注意電壓為 3.3V,Arduino 的 9 ~ 13 腳位都需連接。

Arduino與MFRC522的電路連接示意圖 Arduino Uno 與 MFRC522 晶片接線示意圖 (圖片來源:Electronic Clinic)

安裝 MFRC522 模組

接下來請將 Arduino 連接到電腦,並啟動 Arduino IDE (需安裝),展開頂部選單查看已連接的裝置,請從列表中選擇被辨識為 Arduino Uno 的硬體。有些 Uno 主機板可能不會被辨識到,這時請嘗試選擇除了 COM1 以外的選項,直到連接成功。本文使用的是「COM7」。

Arduino IDE的硬體選擇,正選中COM7的Arduino Uno

為了讓 IDE 能存取 RFID 晶片,請從左側的選項中進入 Library Manager,搜尋「mfrc522」後安裝由 Github Community 開發的 MFRC522 模組。

Arduino IDE的Library Manager,正搜尋mfrc522並安裝

燒錄 RFID 讀取程式

Arduino 需要燒錄程式後才能讀取 RFID 的資訊,請從頂部選單選擇 File > Examples > MFRC522,選擇「ReadNUID」來開啟模組作者提供的讀取程式。這時會新開一個 Arduino IDE 的視窗,舊視窗的請直接關閉。

Arduino IDE的範例專案選擇介面,正選中MFRC522的ReadNUID

開啟 ReadNUID 後,請點擊左上角的燒錄按鈕,即可將程式燒錄進 Arduino。燒錄完成後,請點擊右上角來啟動 Serial Monitor,這時請拿 RFID 標籤靠近 MFRC522 晶片,Serial Monitor 會出現「In hex: …」與「In dec: …」的訊息,代表晶片有順利感應到 RFID 標籤的資訊。

本文使用的範例程式是用於偵測 RFID 標籤的「變化」,每次感應的標籤要不同。因此,如果我們重複感應同一個標籤,他會顯示「Card read previously.」,這是正常現象。

Arduino IDE的ReadNUID的燒錄、Serial Monitor

操作到這裡,我們已經完成 MFRC522 與 Arduino 之間的連接與通訊,接下來請關閉 Arduino IDE,下一步將開始操作 Unity 來整合 Arduino 與 RFID 功能。

整合 Unity 與 Arduino

Unity 需要透過 Serial Port 來和 Arduino 通訊,本文採用 Ardity 套件來開發 Unity 與 Arduino 溝通的功能。

安裝 Ardity 套件

請啟動 Unity 專案,從頂部選單的 Window 來打開 Package Manager,再展開視窗左上角的 +,選擇「Install package from git URL…」,再複製 Ardity 套件的連結來安裝。Unity 需要電腦安裝 Git 才能從 GitHub 上下載套件,安裝完成後請重新啟動電腦來生效。

Unity的Package Manager的安裝方式選擇,正選中使用git URL安裝

我們修改 Ardity 原專案來讓它更好使用,請使用以下連結來安裝:

1https://github.com/tedliou/Ardity.git?path=Packages/ardity#2.0.1

接收 Arduino 訊息

Ardity 提供的 SerialController 能快速連接 Arduino,請點擊 Project 面板右上角的按鈕來顯示隱藏檔案,再展開 Packages 資料夾,拖曳 Ardity > Prefabs 下的 SerialController 到場景中。

選取 SerialController,請調整 Port Name 為先前連接 Arduino 用的名稱 (本文為 COM7),Baud Rate 為 9600,Max Unread Messages 為 10 (可調高一些,讓系統能一次接收更多訊息)。

Unity拖曳Ardity的SerialController Prefab到場景的示意圖

接下來我們要寫一個程式來從 SerialController 接收 Arduino 的訊息,請建立一個空物件和附加在空物件的 C# 腳本,都命名為 ArduinoController。

Unity建立ArduinoController空物件和腳本,並把腳本附加在空物間上

我們要讓 SerialController 將 Arduino 訊息傳到 ArduinoController,請再一次選取 SerialController,拖曳 ArduinoController 空物件到 Message Listener 欄位。

Unity拖曳ArduinoController到SerialController的Message Listener欄位

編輯 ArduinoController 腳本,建立 OnConnectionEvent 與 OnMessageArrived 方法,用來接收 SerialController 輸入的訊息。

 1using UnityEngine;
 2
 3public class ArduinoController : MonoBehaviour
 4{
 5    private void OnConnectionEvent(bool state)
 6    {
 7        Debug.Log($"連線狀態:{state}");
 8    }
 9
10    private void OnMessageArrived(string msg)
11    {
12        Debug.Log($"接收資料:{msg}");
13    }
14}

執行 Unity 專案,這時 SerialController 會連線到 Arduino,並開始接收 MFRC522 的辨識結果。拿 RFID 標籤靠近 MFRC522 晶片,Console 面板會顯示 Unity 接收到的訊息。

Unity的Console,顯示MFRC522的RFID標籤辨識結果,可顯示16進位和10進位的UID

讀取 RFID 標籤編號

本文辨識開頭為「In Hex:」開頭的字串,並擷取後面的 16 進位 RFID 標籤編號,用來辨識各個標籤的差異。使用 String 的 StartsWith 方法來過濾字串開頭,再用 Substring 擷取 RFID 編號,最後用 Replace 刪除編號中的所有空白字元。

 1using UnityEngine;
 2
 3public class ArduinoController : MonoBehaviour
 4{
 5    private void OnConnectionEvent(bool state)
 6    {
 7        Debug.Log($"連線狀態:{state}");
 8    }
 9
10    private void OnMessageArrived(string msg)
11    {
12        Debug.Log($"接收資料:{msg}");
13
14        if (msg.StartsWith("In hex:"))
15        {
16            var hex = msg.Substring(7).Replace(" ", "");
17            Debug.Log($"辨識結果:{hex}");
18        }
19    }
20}

再次執行 Unity 專案,感應 RFID 標籤後,Console 面板即可顯示格式化的標籤編號。

Unity的Console,顯示MFRC522的RFID標籤辨識結果,只顯示16進位、已經格式化刪除空白的編號

分類 RFID 標籤編號

本文的目標是感應 3 個 RFID 標籤時,系統能根據感應到的標籤編號來分類,轉換成「選項 A」、「選項 B」與「選項 C」。請編輯 ArduinoController,使用 switch 語法根據 RFID 標籤編號來分類,並將分類結果儲存到靜態變數「option」。

 1using UnityEngine;
 2
 3public class ArduinoController : MonoBehaviour
 4{
 5    public static string option = "無選項";
 6
 7    private void OnConnectionEvent(bool state)
 8    {
 9        Debug.Log($"連線狀態:{state}");
10    }
11
12    private void OnMessageArrived(string msg)
13    {
14        Debug.Log($"接收資料:{msg}");
15
16        if (msg.StartsWith("In hex:"))
17        {
18            var hex = msg.Substring(7).Replace(" ", "");
19            Debug.Log($"辨識結果:{hex}");
20
21            switch (hex)
22            {
23                case "43223319":
24                    option = "選項 A";
25                    break;
26                case "7325A11A":
27                    option = "選項 B";
28                    break;
29                case "B365A11A":
30                    option = "選項 C";
31                    break;
32            }
33
34            Debug.Log($"選項切換:{option}");
35        }
36    }
37}

執行 Unity 專案,感應到 RFID 標籤後,Console 面板將會顯示分類後的選項名稱。

Unity的Console,顯示MFRC522的RFID標籤辨識的分類結果,將標籤UID轉變為系統內的分類名稱

至此,我們已經完成 Unity 與 Arduino 之間的通訊,也能從 Arduino 傳入的訊息中讀取 RFID 標籤的編號,並取一個名稱來做分類,最後本文將透過設計一個簡單的互動「變色球」來進行應用。

設計互動功能

人的「互動」、系統的「處理」與產生的「回饋」是人機互動的基礎,我們讓使用者拿 RFID 標籤來感應 MFRC522,Arduino 讀取 MFRC522 獲得的感應資料,Unity 再讀取、分類 Arduino 的訊息。目前已完成「互動」和「處理」的功能,現在我們要使用 Unity 來設計一個簡單的「回饋」,當使用者感應 RFID 標籤時,畫面上的球體會變成相應的顏色。

請在場景上建立一個命名為 Ball 的球體,再建立 BallController 腳本並附加到 Ball 上。

Unity的場景介面,介面中有一個白色球體,並且該物件附加了BallController腳本

接下來要開發球的變色功能,請編輯 BallController,讓系統偵測到 ArduinoController 的 RFID 分類結果 option 發生變化時,會根據分類的選項 A ~ C 來改變 Ball 的顏色,A、B、C 分別對應於藍色、紅色、黃色。如果是系統剛啟動、option 是初始值「無選項」的話,Ball 會變成白色。

 1using UnityEngine;
 2
 3public class BallController : MonoBehaviour
 4{
 5    private string _lastOption;
 6
 7    private void Update()
 8    {
 9        if (_lastOption == ArduinoController.option)
10            return;
11
12        _lastOption = ArduinoController.option;
13        var mat = GetComponent<MeshRenderer>().material;
14        
15        switch (_lastOption)
16        {
17            case "無選項":
18                mat.color = Color.white;
19                break;
20            case "選項 A":
21                mat.color = Color.blue;
22                break;
23            case "選項 B":
24                mat.color = Color.red;
25                break;
26            case "選項 C":
27                mat.color = Color.yellow;
28                break;
29        }
30    }
31}

最後執行 Unity 專案,感應不同的 RFID 標籤後,球體將會根據感應後的分類來即時改變顏色。

Unity的場景介面,介面中有一個白色球體,在感應到RFID標籤後會變色

參考資料

Ted Liou

請追蹤我,這裡會分享實用的技術研發資訊!