StageUp
Mobile SDKDeep Link

Unity

AdStage In-App Event Integration Guide (Unity)

Table of Contents

  1. Overview
  2. Basic Setup
  3. Type-Safe Event Tracking
  4. Standard Event Catalog
  5. Troubleshooting

Overview

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.

Supported Platforms

  • ✅ Android (API 21+)
  • ✅ iOS (12.0+)

Basic Setup

1. Install the Package

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"
  }
}

2. Initialize the SDK

using AdStageSDK;
using UnityEngine;
 
public class GameManager : MonoBehaviour
{
    void Start()
    {
        // AdStage 초기화
        AdStage.Initialize(
            apiKey: "your-api-key-here"
        );
        
        Debug.Log("✅ AdStage SDK 초기화 완료");
    }
}

3. Android Setup (AndroidManifest.xml)

<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>

4. iOS Setup (Info.plist)

<!-- 네트워크 사용 권한 -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
</dict>

Type-Safe Event Tracking

1. The Simplest Approach

using AdStageSDK;
using AdStageSDK.Models;
 
public class GameController : MonoBehaviour
{
    void Start()
    {
        // 파라미터 없는 이벤트
        AdStage.TrackEvent(AdStageEvent.Custom());
        
        // 로그인 이벤트
        AdStage.TrackEvent(
            AdStageEvent.Login(method: "email")
        );
    }
}

2. Purchase Event (Validation Example)

// ✅ 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"
    )
);

3. Using Callbacks

AdStage.TrackEvent(
    AdStageEvent.Purchase(
        value: 9900.0,
        currency: "KRW",
        transactionId: "ORDER_001"
    ),
    onSuccess: (success) => {
        Debug.Log("✅ 이벤트 전송 성공");
    },
    onError: (error) => {
        Debug.LogError($"❌ 이벤트 전송 실패: {error}");
    }
);

4. Custom Events (Automatic event_name Promotion)

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));

Standard Event Catalog

The AdStage Unity SDK provides 46 standard events.

📌 Ad Tracking (4)

// 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" }
    }
));

👤 User Lifecycle (5)

// 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());

📄 Content Viewing (6)

// 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"
));

🛒 E-commerce (8)

// 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"
));

🎮 Progress/Achievement (4)

// 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"));

💬 Interaction (3)

// 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"));

🎮 Game-Specific (4)

// 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"
));

📅 Subscription/Trial (3)

// 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"));

Troubleshooting

1. Events Are Not Sent in the Unity Editor

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

2. Events Are Not Sent After an Android Build

Checklist:

  1. Check Logcat: adb logcat | grep -i adstage
  2. Internet permission: Verify the INTERNET permission in AndroidManifest.xml
  3. Disable Minify (for testing): Check the ProGuard/R8 settings
// 디버그 빌드로 테스트
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;

3. Events Are Not Sent After an iOS Build

Checklist:

  1. Check the Xcode Console: Look for error messages
  2. Framework linking: Verify that AdapterAdStage.framework is embedded
  3. Bitcode setting: Disable Bitcode in Build Settings

4. IL2CPP Build Error

Solution:

// link.xml 파일 생성
<linker>
    <assembly fullname="AdStageSDK" preserve="all"/>
    <assembly fullname="AdStageSDK.Models" preserve="all"/>
</linker>

5. JSON Serialization Error

Problem:

System.ArgumentException: Invalid JSON

Solution:

// Dictionary 값이 null인지 확인
var parameters = new Dictionary<string, object>
{
    { "key1", value ?? "default" },
    { "key2", string.IsNullOrEmpty(value2) ? "unknown" : value2 }
};

6. Currency Code Validation Error

// ❌ 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")  // 일본 엔

References

Standard References


FAQ

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> {...})


Support

Contact:


© 2025 NBase. All rights reserved.

Table of Contents