Unity
- 概述
- 專案設定
- Unity 專案設定
- Android 平台設定
- iOS 平台設定
- 建立深層連結
- 疑難排解
AdStage DeepLink SDK for Unity 提供以下功能:
- 即時深層連結:透過 URL Scheme、App Link/Universal Links 即時處理
- 延遲深層連結:應用程式安裝後首次啟動時自動還原
- 動態深層連結建立:透過伺服器 API 建立可追蹤的連結
- 歸因追蹤:以 UTM 參數為基礎的行銷分析
- 跨平台:Android/iOS 使用相同 API
- URL Scheme:
myapp://promo/summer
- Android App Links:
https://go.myapp.com/abc123
- iOS Universal Links:
https://go.myapp.com/abc123
- 延遲深層連結:未安裝應用程式時 商店 → 安裝 → 啟動應用程式時還原
透過 Package Manager 安裝:
Window → Package Manager → + → Add package from git URL
https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package
或直接編輯 manifest.json:
{
"dependencies": {
"com.nbase.adstage": "https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package#3.0.0"
}
}
安裝套件時會自動包含:
- Newtonsoft.Json:JSON 序列化
- Native 外掛:iOS/Android 橋接
using AdStageSDK;
using UnityEngine;
public class AdStageInitializer : MonoBehaviour
{
void Start()
{
// AdStage 初始化
AdStage.Initialize(
apiKey: "your-api-key-here"
);
// 註冊深層連結監聽器
SetupDeepLinkListener();
Debug.Log("✅ AdStage SDK 初始化完成");
}
private void SetupDeepLinkListener()
{
AdStage.SetDeepLinkListener(
onDeepLink: (data) => {
Debug.Log($"✅ 收到深層連結: {data.shortPath}");
if (data.parameters != null && data.parameters.Count > 0)
{
foreach (var param in data.parameters)
{
Debug.Log($" - {param.Key}: {param.Value}");
}
}
},
onError: (error) => {
Debug.LogError($"❌ 深層連結失敗: {error}");
}
);
}
}
建立 Assets/Plugins/Android/AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:allowBackup="true"
android:icon="@drawable/app_icon"
android:label="@string/app_name">
<activity
android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector"
android:screenOrientation="fullSensor"
android:launchMode="singleTask"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:exported="true">
<!-- 預設啟動器 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- URL Scheme 深層連結 -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="your_app_scheme" />
</intent-filter>
</activity>
</application>
</manifest>
android:launchMode="singleTask"
- ✅ singleTask:重複使用既有的 Activity(建議)
- ⚠️ singleTop:僅在位於堆疊最上層時才重複使用
- ❌ standard:每次都建立新執行個體(會產生深層連結重複)
<!-- URL Scheme 設定 -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>your_ios_scheme</string>
</array>
</dict>
</array>
public async void CreateDetailedDeepLink()
{
try
{
var builder = new DeepLinkBuilder("Unity Test Link")
.SetDescription("Unity SDK 測試")
.SetCampaign("unity_test")
.SetChannel("app_channel")
.SetRedirectType(RedirectType.APP)
.SetAndroidConfig("your.package.name","your_aos_scheme", "https://yourdomain.com")
.SetIOSConfig("your.appstoreid", "your_ios_scheme", "https://yourdomain.com")
.SetWebConfig("https://yourdomain.com")
.AddParameter("user_id", "value")
.AddParameter("test", "true");
AdStage.CreateDeeplink(
builder: builder,
onSuccess: (shortUrl) =>
{
InAppLog("✅ 深層連結建立成功!");
InAppLog($" URL: {shortUrl}");
},
onError: (error) =>
{
InAppLog($"❌ 深層連結建立失敗: {error}");
}
);
}
catch (System.Exception e)
{
Debug.LogError($"❌ 錯誤: {e.Message}");
}
}
public enum RedirectType
{
STORE, // 前往商店
APP, // 未安裝應用程式時 → 前往商店
// 已安裝應用程式時 → 啟動應用程式(即時深層連結)
WEB // 一律前往網頁 URL
// 與應用程式是否安裝無關
}
Android 深層連結流程:
使用者點擊深層連結 (myapp://abc123)
↓
Android System 建立 Intent
↓
UnityPlayerActivity 啟動/恢復
↓
AdStageLifecyclePlugin.onActivityCreated/Resumed()
↓
AdStageUnityWrapper.handleIntent(intent)
↓
AdStage.handleIntent(context, intent)
↓
DeeplinkHandler.handleIntent()
├─ 擷取 URI: myapp://abc123
├─ 解析 shortPath: abc123
├─ 呼叫 API: GET /deeplinks/abc123
└─ DeeplinkListener.onDeeplinkReceived()
↓
UnitySendMessage("AdStageCallbackReceiver", "OnDeepLinkReceived", json)
↓
AdStageCallbackReceiver.OnDeepLinkReceived(json)
↓
呼叫使用者回呼
iOS 深層連結流程:
使用者點擊深層連結 (myapp://abc123)
↓
iOS System 傳遞 URL
↓
AdStageUnityAppController.application:openURL: 或
AdStageUnityAppController.application:continueUserActivity:
↓
AdStageUnityBridge.AdStageIOS_HandleDeepLink(url)
↓
AdStageManager.shared.handleDeepLink(url)
↓
DeepLinkManager.handleDeepLink()
├─ 解析 URL
├─ 呼叫 API
└─ DeepLinkDelegate.onDeepLinkReceived()
↓
UnitySendMessage("AdStageCallbackReceiver", "OnDeepLinkReceived", json)
↓
AdStageCallbackReceiver.OnDeepLinkReceived(json)
↓
呼叫使用者回呼
這是正常行為! AdStage SDK 僅在行動平台(Android/iOS)上運作。
在 Editor 中呼叫 AdStage.Initialize() 時 IsInitialized() 會回傳 false,
深層連結回呼僅能在實機上接收。
確認方法:
#if UNITY_EDITOR
Debug.Log("📊 [Editor Mode] 深層連結僅在實機上運作");
#endif
測試方法: 將實際的 Android/iOS 建置安裝到裝置後,用下方疑難排解中的
Intent / URL Scheme 測試(第 2 項、第 3 項)確認深層連結的接收。
檢查清單:
-
確認 AndroidManifest.xml
- 確認
android:launchMode="singleTask" 設定
- 確認 Intent Filter 是否正確
-
確認 adb logcat
adb logcat | grep -i adstage
- Intent 測試
# URL Scheme 測試
adb shell am start -W -a android.intent.action.VIEW -d "myapp://promo/summer" com.example.myapp
# HTTPS App Link 測試
adb shell am start -W -a android.intent.action.VIEW -d "https://go.myapp.com/abc123" com.example.myapp
檢查清單:
-
確認 Info.plist
- CFBundleURLTypes 設定
- Associated Domains 設定
-
Universal Links 驗證
# 確認 Apple App Site Association 檔案
curl https://go.myapp.com/.well-known/apple-app-site-association
- 確認 Xcode Console
Android:
# 確認 Install Referrer
adb shell dumpsys package com.example.myapp | grep -i referrer
解決方法:
- 在 AndroidManifest.xml 中新增權限:
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
- 在 Play Console 中設定 Install Referrer
原因: 使用了 launchMode="standard"
解決:
<!-- AndroidManifest.xml -->
android:launchMode="singleTask"
問題:
TypeLoadException: Could not load type 'AdStageSDK.DeepLinkData'
解決: 建立 link.xml 檔案
Assets/link.xml:
<linker>
<assembly fullname="AdStageSDK" preserve="all"/>
<assembly fullname="AdStageSDK.Models" preserve="all"/>
<assembly fullname="Newtonsoft.Json" preserve="all"/>
</linker>
問題:
JsonSerializationException: Error converting value
解決:
// Parameters 使用 Dictionary<string, object>
var parameters = new Dictionary<string, object>
{
{ "key1", "value1" },
{ "key2", 123 }, // int 也可以
{ "key3", true } // bool 也可以
};
確認方法:
# Digital Asset Links 驗證
curl https://go.myapp.com/.well-known/assetlinks.json
檢查清單:
- ✅ 使用 HTTPS
- ✅ Content-Type:
application/json
- ✅ 確認 SHA256 指紋是否正確
- ✅ 套件名稱一致
Q: 可以在 Unity Editor 中測試深層連結嗎?
A: 不行。SDK 僅在行動平台上運作,因此深層連結測試必須在實際的 Android/iOS 裝置上進行。
Q: Android 與 iOS 可以使用相同的深層連結 URL 嗎?
A: 可以,URL Scheme 與 HTTPS 連結都可以相同地使用。
Q: 延遲深層連結是如何運作的?
A: 安裝應用程式 → 首次啟動 → 查詢 Install Referrer → 還原已儲存的深層連結 → 呼叫回呼
Q: 深層連結的參數個數有限制嗎?
A: 伺服器沒有限制,但請考量 URL 長度限制(約 2000 個字元)。
Q: 離線狀態下深層連結也能運作嗎?
A: 即時深層連結需要網路。延遲深層連結會被快取,離線狀態下也能還原。
Q: 在 Unity WebGL 上也能運作嗎?
A: WebGL 無法使用原生外掛,因此不支援。在 Web 環境中請直接解析 URL 參數。
聯絡方式:
© 2025 NBase. All rights reserved.