QR code generator in Unity
需求要在遊戲中顯示 QR code,該 QR code 帶某網站的網址,原先是計畫用工具生成 QR code 後,放入 Unity 當作貼圖使用。
但考慮到這網址可以從遊戲伺服器資料拿到,那為何不用動態產生 QRCode,省去未來網址修改,替換貼圖的麻煩呢?紀錄實作此功能的過程。
QR code,沒實作過,也不懂其圖像規格,因此第一個想法是想直接從網路上,撈現成的函數庫使用,而不是了解規格後自己實作。
很幸運的,在 Github 找到一套可產生 QR code 的函數庫 codebude/QRCoder 可以使用,而且有支援 Unity 的實作。
下載 Github 該專案中的 QRCoder 資料夾內容,直接貼到遊戲專案 (/Assets/Plugins/QRCoder) 中,然後調整以下動作,使得能夠正常編譯:
-
移除 PayloadGenerator.cs,由於 C# 版本緣故,裡頭實作語法 (Syntax) 無法編譯,又沒運用到裡頭的 Payload (例如產生 Bitcoin 付款連結,產生 Wi-Fi 連結等),所以直接移除
-
移除 C# project 資料,移除不會用到的 /Properties,.csproj,.dll 等等
-
移除無法使用的實作,部分實作使用到 Unity Mono C# 所沒有引用的函數庫,例如 System.Drawing,無法編譯且在 Unity 又使用不到,移除 QRCode.cs,SvgQRCode.cs,BitmapByteQRCode.cs,Base64QRCode.cs。
-
最後僅留下核心檔案 AbstractQRCode.cs,QRCodeData.cs,QRCodeGenerator.cs,以及重要的 Unity 實作 UnityQRCode.cs
-
修改造成 error CS1061 的錯誤,主因是 .net 版本不同,在 QRCodeGenerator.cs 檔案開頭定義符號
#define NET40
後,編譯錯誤就可解決。或是手動修改那幾段編譯不過的程式碼。
能夠在 Unity 編譯後,使用以下範例程式碼便可在 UI.Image 中顯示動態產生的 QR code 了。
using QRCoder;
using UnityEngine;
using UnityEngine.UI;
// Generate QR code texture
var link = "http://example.com";
var qrGenerator = new QRCodeGenerator();
var qrCodeData = qrGenerator.CreateQrCode(link, QRCodeGenerator.ECCLevel.M);
var qrCode = new UnityQRCode(qrCodeData);
var qrCodeImage = qrCode.GetGraphic(20);
// Create sprite & display
var sprite = Sprite.Create(qrCodeImage, new Rect(0, 0, qrCodeImage.width, qrCodeImage.height), new Vector2(.5f, .5f));
var image = this.GetComponent();
image.sprite = sprite;
QRCodeGenerator.ECCLevel 表示容錯能力 (error correction rate),根據 wiki 資料 分成以下幾種,容錯率越高其圖形越大,一般使用 15% 容錯率:
- ECCLevel.L (Low),7% 的字碼可被修正
- ECCLevel.M (Medium),15% 的字碼可被修正
- ECCLevel.Q (Quartile),25% 的字碼可被修正
- ECCLevel.H (High),30% 的字碼可被修正
若考慮資源釋放問題,可以利用 using 來釋放:
Texture2D CreateQRCode(string data, QRCodeGenerator.ECCLevel level = QRCodeGenerator.ECCLevel.M)
{
using (var qrGenerator = new QRCodeGenerator())
{
using (var qrCodeData = qrGenerator.CreateQrCode(data, this.level))
{
return new UnityQRCode(qrCodeData).GetGraphic(20);
}
}
}
沒有留言: