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.