Unity
개요
기본 설정
타입 안전 이벤트 전송
표준 이벤트 카탈로그
트러블슈팅
AdStage Unity SDK v3.0은 타입 안전한 이벤트 시스템 을 도입하여 컴파일 타임에 오류를 방지하고 Android/iOS 네이티브 SDK와 완벽히 호환됩니다.
✅ Android (API 21+)
✅ iOS (12.0+)
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"
}
}
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 }" );
}
);
표준 이벤트 외에 앱 고유의 이벤트를 전송할 때는 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개의 표준 이벤트를 제공합니다.
// 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" ,
itemId : "PROD_789" ,
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" ));
정상 동작입니다! Editor에서는 로그만 출력되고 실제 전송은 안 됩니다.
확인 방법:
# if UNITY_EDITOR
Debug. Log ( "📊 [Editor Mode] 이벤트는 실제 기기에서만 전송됩니다" );
# endif
체크리스트:
Logcat 확인 : adb logcat | grep -i adstage
인터넷 권한 : AndroidManifest.xml에 INTERNET 권한 확인
Minify 비활성화 (테스트): ProGuard/R8 설정 확인
// 디버그 빌드로 테스트
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;
체크리스트:
Xcode Console 확인 : 에러 메시지 확인
Framework 링크 : AdapterAdStage.framework 임베드 확인
Bitcode 설정 : Build Settings에서 Bitcode 비활성화
해결:
// link.xml 파일 생성
< linker >
< assembly fullname = "AdStageSDK" preserve = "all" />
< assembly fullname = "AdStageSDK.Models" preserve = "all" />
</ linker >
문제:
System.ArgumentException: Invalid JSON
해결:
// 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: 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.