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)
↓
사용자 콜백 호출
정상 동작입니다! Editor에서는 로그만 출력됩니다.
테스트 방법:
#if UNITY_EDITOR
[MenuItem("AdStage/Test DeepLink")]
public static void TestDeepLink()
{
var testData = new DeepLinkData
{
ShortPath = "TEST123",
Source = DeepLinkSource.Realtime,
Parameters = new Dictionary<string, string>
{
{ "promo", "EDITOR_TEST" }
}
};
AdStage.SimulateDeepLink(testData);
}
#endif
체크리스트:
-
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: Editor에서는 AdStage.SimulateDeepLink() 메서드로 시뮬레이션 가능합니다.
Q: Android와 iOS에서 동일한 딥링크 URL을 사용할 수 있나요?
A: 예, URL Scheme과 HTTPS 링크 모두 동일하게 사용 가능합니다.
Q: 디퍼드 딥링크는 어떻게 동작하나요?
A: 앱 설치 → 첫 실행 → Install Referrer 조회 → 저장된 딥링크 복원 → 콜백 호출
Q: 딥링크 파라미터 개수 제한이 있나요?
A: 서버 제한은 없으나, URL 길이 제한(~2000자)을 고려하세요.
Q: 오프라인에서도 딥링크가 동작하나요?
A: 실시간 딥링크는 네트워크 필요. 디퍼드 딥링크는 캐시되어 오프라인에서도 복원됩니다.
Q: Unity WebGL에서도 동작하나요?
A: WebGL은 네이티브 플러그인을 사용할 수 없어 지원하지 않습니다. 웹 환경에서는 URL 파라미터를 직접 파싱하세요.
연락처:
© 2025 NBase. All rights reserved.