StageUp
모바일 SDK인앱 이벤트

Unity

AdStage 인앱 이벤트 통합 가이드 (Unity)

목차

  1. 개요
  2. 기본 설정
  3. 타입 안전 이벤트 전송
  4. 표준 이벤트 카탈로그
  5. 트러블슈팅

개요

AdStage Unity SDK v3.0은 타입 안전한 이벤트 시스템을 도입하여 컴파일 타임에 오류를 방지하고 Android/iOS 네이티브 SDK와 완벽히 호환됩니다.

지원 플랫폼

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

기본 설정

1. 패키지 설치

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

2. 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 설정 (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 설정 (Info.plist)

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

타입 안전 이벤트 전송

1. 가장 간단한 방식

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

2. 구매 이벤트 (검증 예제)

// ✅ 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. 콜백 사용

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

4. 커스텀 이벤트 (event_name 자동 승격)

표준 이벤트 외에 앱 고유의 이벤트를 전송할 때는 AdStageEvent.Custom을 사용합니다. 파라미터에 event_name 키를 포함하면, 해당 값이 실제 이벤트 이름으로 자동 승격되어 대시보드에 저장됩니다.

// 예: '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));

표준 이벤트 카탈로그

AdStage Unity SDK는 46개의 표준 이벤트를 제공합니다.

📌 광고 추적 (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" }
    }
));

👤 사용자 라이프사이클 (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());

📄 콘텐츠 조회 (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"
));

🛒 전자상거래 (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"
));

🎮 진행/성취 (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"));

💬 상호작용 (3개)

// 1. 검색
AdStage.TrackEvent(AdStageEvent.Search(searchTerm: "gaming laptop"));
 
// 2. 공유
AdStage.TrackEvent(AdStageEvent.Share(
    contentType: "product",
    itemId: "PROD_789",
    method: "kakao"
));
 
// 3. 광고 클릭
AdStage.TrackEvent(AdStageEvent.AdClick(adPlatform: "unity", adSource:"unity_source", adFormat:"unity_format", adUnitName: "AD_12345"));

🎮 게임 특화 (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"
));

📅 구독/체험 (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"));

트러블슈팅

1. Unity Editor에서 이벤트가 전송되지 않음

정상 동작입니다! Editor에서는 로그만 출력되고 실제 전송은 안 됩니다.

확인 방법:

#if UNITY_EDITOR
Debug.Log("📊 [Editor Mode] 이벤트는 실제 기기에서만 전송됩니다");
#endif

2. Android 빌드 후 이벤트가 전송되지 않음

체크리스트:

  1. Logcat 확인: adb logcat | grep -i adstage
  2. 인터넷 권한: AndroidManifest.xml에 INTERNET 권한 확인
  3. Minify 비활성화 (테스트): ProGuard/R8 설정 확인
// 디버그 빌드로 테스트
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;

3. iOS 빌드 후 이벤트가 전송되지 않음

체크리스트:

  1. Xcode Console 확인: 에러 메시지 확인
  2. Framework 링크: AdapterAdStage.framework 임베드 확인
  3. Bitcode 설정: Build Settings에서 Bitcode 비활성화

4. IL2CPP 빌드 에러

해결:

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

5. JSON 직렬화 에러

문제:

System.ArgumentException: Invalid JSON

해결:

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

6. 통화 코드 검증 에러

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

참고 자료

표준 참조


FAQ

Q: Unity Editor에서 테스트할 수 있나요?
A: Editor에서는 로그만 출력됩니다. 실제 테스트는 기기에서 해야 합니다.

Q: Android와 iOS에서 동일하게 작동하나요?
A: 예, 46개 이벤트가 모두 동일하게 작동합니다.

Q: Unity IAP와 함께 사용할 수 있나요?
A: 예, ProcessPurchase 콜백에서 AdStage 이벤트를 호출하면 됩니다.

Q: 오프라인에서도 작동하나요?
A: 예, 네이티브 SDK가 자동으로 이벤트를 큐에 저장하고 네트워크 복구 시 전송합니다.

Q: 커스텀 이벤트는 어떻게 전송하나요?
A: AdStageEvent.Custom(new Dictionary<string, object> {...}) 사용


지원

연락처:


© 2025 NBase. All rights reserved.

목차