Unity
ภาพรวม
การตั้งค่าโปรเจกต์
การตั้งค่าโปรเจกต์ Unity
การตั้งค่าแพลตฟอร์ม Android
การตั้งค่าแพลตฟอร์ม iOS
การสร้าง deep link
การแก้ไขปัญหา
AdStage DeepLink SDK for Unity มีฟีเจอร์ดังต่อไปนี้:
Deep link แบบเรียลไทม์ : ประมวลผลทันทีผ่าน URL Scheme และ App Link/Universal Links
Deferred deep link : กู้คืนโดยอัตโนมัติเมื่อเปิดแอปครั้งแรกหลังการติดตั้ง
การสร้าง deep link แบบไดนามิก : สร้างลิงก์ที่ติดตามได้ผ่าน API ของเซิร์ฟเวอร์
การติดตาม attribution : การวิเคราะห์การตลาดบนพื้นฐานของพารามิเตอร์ UTM
ข้ามแพลตฟอร์ม : API เดียวกันสำหรับ Android/iOS
URL Scheme : myapp://promo/summer
Android App Links : https://go.myapp.com/abc123
iOS Universal Links : https://go.myapp.com/abc123
Deferred deep link : เมื่อยังไม่ได้ติดตั้งแอป จะกู้คืนเมื่อ สโตร์ → ติดตั้ง → เปิดแอป
การติดตั้งผ่าน 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 : การ serialize JSON
Native plugin : บริดจ์ 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 : สร้างอินสแตนซ์ใหม่ทุกครั้ง (ทำให้ deep link ซ้ำซ้อน)
<!-- 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로 이동
// 앱 설치 여부 무관
}
ขั้นตอนการทำงานของ deep link บน 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)
↓
사용자 콜백 호출
ขั้นตอนการทำงานของ deep link บน 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 และ
callback ของ deep link จะถูกรับเฉพาะบนเครื่องจริงเท่านั้น
วิธีตรวจสอบ:
# if UNITY_EDITOR
Debug. Log ( "📊 [Editor Mode] 딥링크는 실제 기기에서만 동작합니다" );
# endif
วิธีทดสอบ: ติดตั้งบิลด์ Android/iOS จริงลงบนเครื่อง แล้วตรวจสอบการรับ deep link ด้วย
การทดสอบ 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
ตรวจสอบข้อความ error
ตรวจสอบ log การรับ deep link
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" />
ตั้งค่า Install Referrer ใน Play Console
สาเหตุ: ใช้ 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: ทดสอบ deep link ใน Unity Editor ได้ไหม?
A: ไม่ได้ เนื่องจาก SDK ทำงานเฉพาะบนแพลตฟอร์มมือถือเท่านั้น การทดสอบ deep link จึงต้องทำบนเครื่อง Android/iOS จริง
Q: ใช้ deep link URL เดียวกันบน Android และ iOS ได้ไหม?
A: ได้ ทั้ง URL Scheme และลิงก์ HTTPS ใช้ได้เหมือนกัน
Q: Deferred deep link ทำงานอย่างไร?
A: ติดตั้งแอป → เปิดครั้งแรก → ค้นหา Install Referrer → กู้คืน deep link ที่บันทึกไว้ → เรียก callback
Q: มีข้อจำกัดจำนวนพารามิเตอร์ของ deep link ไหม?
A: ไม่มีข้อจำกัดที่เซิร์ฟเวอร์ แต่ควรคำนึงถึงข้อจำกัดความยาว URL (~2000 ตัวอักษร)
Q: Deep link ทำงานแบบออฟไลน์ได้ไหม?
A: Deep link แบบเรียลไทม์ต้องใช้เครือข่าย ส่วน deferred deep link จะถูกแคชไว้และกู้คืนได้แม้แบบออฟไลน์
Q: ทำงานบน Unity WebGL ได้ไหม?
A: WebGL ไม่สามารถใช้ native plugin ได้ จึงไม่รองรับ ในสภาพแวดล้อมเว็บให้ parse พารามิเตอร์ URL โดยตรง
ช่องทางติดต่อ:
© 2025 NBase. All rights reserved.