Unity
Overview
Basic Setup
Type-Safe Event Tracking
Standard Event Catalog
Troubleshooting
AdStage Unity SDK v3.0 introduces a type-safe event system that prevents errors at compile time and is fully compatible with the Android/iOS native SDKs.
✅ Android (API 21+)
✅ iOS (12.0+)
Installation via Package Manager:
Window → Package Manager → + → Add package from git URL
https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package
Or edit manifest.json directly:
{
"dependencies" : {
"com.nbase.adstage" : "https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package#3.0.0"
}
}
using AdStageSDK ;
using UnityEngine ;
public class GameManager : MonoBehaviour
{
void Start ()
{
// AdStage 초기화
AdStage. Initialize (
apiKey : "your-api-key-here"
);
Debug. Log ( "✅ AdStage SDK 초기화 완료" );
}
}
< manifest xmlns:android = "http://schemas.android.com/apk/res/android" >
<!-- 필수 권한 -->
< uses-permission android:name = "android.permission.INTERNET" />
< uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
</ manifest >
<!-- 네트워크 사용 권한 -->
< key >NSAppTransportSecurity</ key >
< dict >
< key >NSAllowsArbitraryLoads</ key >
< false />
</ dict >
using AdStageSDK ;
using AdStageSDK . Models ;
public class GameController : MonoBehaviour
{
void Start ()
{
// 파라미터 없는 이벤트
AdStage. TrackEvent (AdStageEvent. Custom ());
// 로그인 이벤트
AdStage. TrackEvent (
AdStageEvent. Login ( method : "email" )
);
}
}
// ✅ GOOD: value와 currency 함께 제공
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 29.99 ,
currency : "USD" ,
transactionId : "TXN_123456"
)
);
// ❌ BAD: value만 제공 시 런타임 에러!
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 29.99 // ❌ 에러: currency 필수!
)
);
// ✅ GOOD: currency 없이 transactionId만
AdStage. TrackEvent (
AdStageEvent. Purchase (
transactionId : "TXN_123456"
)
);
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 9900.0 ,
currency : "KRW" ,
transactionId : "ORDER_001"
),
onSuccess : ( success ) => {
Debug. Log ( "✅ 이벤트 전송 성공" );
},
onError : ( error ) => {
Debug. LogError ( $"❌ 이벤트 전송 실패: { error }" );
}
);
When sending app-specific events beyond the standard events, use AdStageEvent.Custom.
If you include the event_name key in the parameters, that value is automatically promoted to the actual event name and stored in the dashboard.
// 예: 'promotion_click'이라는 커스텀 이벤트 전송
var promotionParams = new Dictionary < string , object >
{
{ "event_name" , "promotion_click" },
{ "promotion_id" , "summer_sale_2025" },
{ "screen" , "home_banner" }
};
AdStage. TrackEvent (AdStageEvent. Custom (promotionParams));
// 대시보드에는 "promotion_click" 이벤트로 수집됨
// event_name 없이 일반 커스텀 이벤트
var customParams = new Dictionary < string , object >
{
{ "action" , "button_click" },
{ "button_id" , "promo_banner" },
{ "screen" , "home" },
{ "timestamp" , DateTimeOffset.UtcNow. ToUnixTimeSeconds () }
};
AdStage. TrackEvent (AdStageEvent. Custom (customParams));
// 대시보드에는 "custom" 이벤트로 수집됨
// Click, View도 자유 파라미터 지원
var clickParams = new Dictionary < string , object >
{
{ "campaign_id" , "SUMMER2025" },
{ "ad_group" , "electronics" }
};
AdStage. TrackEvent (AdStageEvent. Click (clickParams));
The AdStage Unity SDK provides 46 standard events.
// 1. 광고 클릭
AdStage. TrackEvent (AdStageEvent. Click (
new Dictionary < string , object > { { "campaign_id" , "CAMP_123" } }
));
// 2. 광고 노출
AdStage. TrackEvent (AdStageEvent. View (
new Dictionary < string , object > { { "impression_id" , "IMP_456" } }
));
// 3. 앱 설치
AdStage. TrackEvent (AdStageEvent. Install ());
// 4. 커스텀 이벤트 (event_name으로 이벤트 이름 지정)
AdStage. TrackEvent (AdStageEvent. Custom (
new Dictionary < string , object > {
{ "event_name" , "promotion_click" },
{ "promotion_id" , "summer_sale_2025" }
}
));
// 1. 회원가입 완료
AdStage. TrackEvent (AdStageEvent. SignUp ( method : "google" ));
// 2. 회원가입 시작
AdStage. TrackEvent (AdStageEvent. SignUpStart ());
// 3. 로그인
AdStage. TrackEvent (AdStageEvent. Login ( method : "email" ));
// 4. 로그아웃
AdStage. TrackEvent (AdStageEvent. Logout ());
// 5. 앱 최초 실행
AdStage. TrackEvent (AdStageEvent. FirstOpen ());
// 1. 홈 화면
AdStage. TrackEvent (AdStageEvent. HomeView ());
// 2. 상품 목록
AdStage. TrackEvent (AdStageEvent. ProductListView ( itemCategory : "electronics" ));
// 3. 검색 결과
AdStage. TrackEvent (AdStageEvent. SearchResultView ( searchTerm : "wireless headphones" ));
// 4. 상품 상세
AdStage. TrackEvent (AdStageEvent. ProductDetailsView (
itemId : "PROD_123" ,
itemName : "Wireless Earbuds"
));
// 5. 페이지 조회 (웹)
AdStage. TrackEvent (AdStageEvent. PageView (
pageUrl : "https://example.com/products" ,
pageTitle : "Products"
));
// 6. 화면 조회 (Unity Scene)
AdStage. TrackEvent (AdStageEvent. ScreenView (
screenName : "MainMenu" ,
screenClass : "MainMenuScene"
));
// 1. 장바구니 추가
var cartItem = new EcommerceItem (
itemId : "PROD_123" ,
itemName : "Wireless Earbuds" ,
price : 99000.0 ,
quantity : 1
);
AdStage. TrackEvent (AdStageEvent. AddToCart (
value : 99000.0 ,
currency : "KRW" ,
items : new List < EcommerceItem > { cartItem }
));
// 2. 장바구니 제거
AdStage. TrackEvent (AdStageEvent. RemoveFromCart (
value : 50000.0 ,
currency : "KRW"
));
// 3. 위시리스트 추가
AdStage. TrackEvent (AdStageEvent. AddToWishlist (
itemId : "PROD_456" ,
itemName : "Smart Watch"
));
// 4. 결제 정보 입력
AdStage. TrackEvent (AdStageEvent. AddPaymentInfo ( paymentType : "credit_card" ));
// 5. 결제 시작
AdStage. TrackEvent (AdStageEvent. BeginCheckout (
value : 150000.0 ,
currency : "KRW"
));
// 6. 구매 완료 ⭐⭐⭐
var purchaseItems = new List < EcommerceItem >
{
new EcommerceItem (
itemId : "PROD_123" ,
itemName : "Wireless Earbuds" ,
price : 126000.0 ,
quantity : 1
)
};
AdStage. TrackEvent (AdStageEvent. Purchase (
value : 129000.0 ,
currency : "KRW" ,
transactionId : "ORDER_20250105_001" ,
tax : 12900.0 ,
shipping : 3000.0 ,
coupon : "SUMMER2025" ,
items : purchaseItems
));
// 7. 환불
AdStage. TrackEvent (AdStageEvent. Refund (
transactionId : "ORDER_20250105_001" ,
value : 129000.0 ,
currency : "KRW"
));
// 1. 튜토리얼 시작
AdStage. TrackEvent (AdStageEvent. TutorialBegin (
new Dictionary < string , object > { { "tutorial_id" , "intro" } }
));
// 2. 튜토리얼 완료
AdStage. TrackEvent (AdStageEvent. TutorialComplete (
new Dictionary < string , object > { { "duration_seconds" , 120 } }
));
// 3. 레벨 업
AdStage. TrackEvent (AdStageEvent. LevelUp (
level : 25 ,
character : "warrior"
));
// 4. 업적 달성
AdStage. TrackEvent (AdStageEvent. Achievement ( achievementId : "first_win" ));
// 1. 검색
AdStage. TrackEvent (AdStageEvent. Search ( searchTerm : "gaming laptop" ));
// 2. 공유
AdStage. TrackEvent (AdStageEvent. Share (
contentType : "product" ,
method : "kakao"
));
// 3. 광고 클릭
AdStage. TrackEvent (AdStageEvent. AdClick ( adPlatform : "unity" , adSource : "unity_source" , adFormat : "unity_format" , adUnitName : "AD_12345" ));
// 1. 게임 플레이
AdStage. TrackEvent (AdStageEvent. GamePlay (
level : 10 ,
levelName : "Dragon's Lair" ,
character : "mage" ,
contentType : "dungeon"
));
// 2. 보너스 획득
AdStage. TrackEvent (AdStageEvent. AcquireBonus (
contentType : "reward" ,
itemId : "ITEM_123" ,
itemName : "Gold Chest" ,
quantity : 1
));
// 3. 게임 서버 선택
AdStage. TrackEvent (AdStageEvent. SelectGameServer (
contentId : "SERVER_01" ,
contentType : "pvp" ,
itemName : "Asia Server"
));
// 4. 패치 완료
AdStage. TrackEvent (AdStageEvent. CompletePatch (
contentId : "PATCH_2.1.0" ,
contentType : "update"
));
// 1. 무료 체험 시작
AdStage. TrackEvent (AdStageEvent. StartTrial (
value : 9900.0 ,
currency : "KRW" ,
trialDays : 14
));
// 2. 구독 시작
AdStage. TrackEvent (AdStageEvent. Subscribe (
value : 9900.0 ,
currency : "KRW" ,
subscriptionId : "premium_monthly"
));
// 3. 구독 취소
AdStage. TrackEvent (AdStageEvent. Unsubscribe ( subscriptionId : "premium_monthly" ));
This is normal behavior! In the Editor, only logs are printed and no actual sending occurs.
How to verify:
# if UNITY_EDITOR
Debug. Log ( "📊 [Editor Mode] 이벤트는 실제 기기에서만 전송됩니다" );
# endif
Checklist:
Check Logcat : adb logcat | grep -i adstage
Internet permission : Verify the INTERNET permission in AndroidManifest.xml
Disable Minify (for testing): Check the ProGuard/R8 settings
// 디버그 빌드로 테스트
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;
Checklist:
Check the Xcode Console : Look for error messages
Framework linking : Verify that AdapterAdStage.framework is embedded
Bitcode setting : Disable Bitcode in Build Settings
Solution:
// link.xml 파일 생성
< linker >
< assembly fullname = "AdStageSDK" preserve = "all" />
< assembly fullname = "AdStageSDK.Models" preserve = "all" />
</ linker >
Problem:
System.ArgumentException: Invalid JSON
Solution:
// Dictionary 값이 null인지 확인
var parameters = new Dictionary < string , object >
{
{ "key1" , value ?? "default" },
{ "key2" , string . IsNullOrEmpty (value2) ? "unknown" : value2 }
};
// ❌ 2자리 코드
AdStageEvent. Purchase ( value : 100.0 , currency : "KR" )
// ValidationException: "Currency must be 3-letter ISO 4217 code"
// ✅ 3자리 ISO 4217 코드
AdStageEvent. Purchase ( value : 100.0 , currency : "KRW" ) // 한국 원
AdStageEvent. Purchase ( value : 100.0 , currency : "USD" ) // 미국 달러
AdStageEvent. Purchase ( value : 100.0 , currency : "JPY" ) // 일본 엔
Q: Can I test in the Unity Editor?
A: In the Editor, only logs are printed. Actual testing must be done on a device.
Q: Does it work identically on Android and iOS?
A: Yes, all 46 events work identically.
Q: Can I use it together with Unity IAP?
A: Yes, just call the AdStage event in the ProcessPurchase callback.
Q: Does it work offline too?
A: Yes, the native SDK automatically queues events and sends them when the network is restored.
Q: How do I send a custom event?
A: Use AdStageEvent.Custom(new Dictionary<string, object> {...})
Contact:
© 2025 NBase. All rights reserved.