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 Android/iOS native SDKs.
✅ Android (API 21+)
✅ iOS (12.0+)
Install 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 ()
{
// Initialize AdStage
AdStage. Initialize (
apiKey : "your-api-key-here"
);
Debug. Log ( "✅ AdStage SDK Initialized" );
}
}
< manifest xmlns:android = "http://schemas.android.com/apk/res/android" >
<!-- Required permissions -->
< uses-permission android:name = "android.permission.INTERNET" />
< uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
</ manifest >
<!-- Network usage permission -->
< key >NSAppTransportSecurity</ key >
< dict >
< key >NSAllowsArbitraryLoads</ key >
< false />
</ dict >
using AdStageSDK ;
using AdStageSDK . Models ;
public class GameController : MonoBehaviour
{
void Start ()
{
// Event without parameters
AdStage. TrackEvent (AdStageEvent. Custom ());
// Login event
AdStage. TrackEvent (
AdStageEvent. Login ( method : "email" )
);
}
}
// ✅ GOOD: Provide both value and currency
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 29.99 ,
currency : "USD" ,
transactionId : "TXN_123456"
)
);
// ❌ BAD: Runtime error if only value is provided!
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 29.99 // ❌ Error: currency is required!
)
);
// ✅ GOOD: Only transactionId without currency
AdStage. TrackEvent (
AdStageEvent. Purchase (
transactionId : "TXN_123456"
)
);
AdStage. TrackEvent (
AdStageEvent. Purchase (
value : 9900.0 ,
currency : "KRW" ,
transactionId : "ORDER_001"
),
onSuccess : ( success ) => {
Debug. Log ( "✅ Event sent successfully" );
},
onError : ( error ) => {
Debug. LogError ( $"❌ Event sending failed: { error }" );
}
);
For sending app-specific events beyond standard events, use AdStageEvent.Custom.
When you include the event_name key in parameters, that value is automatically promoted as the actual event name and stored in the dashboard.
// Example: Send a custom event named '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));
// Collected as "promotion_click" event in dashboard
// General custom event without 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));
// Collected as "custom" event in dashboard
// Click and View also support custom parameters
var clickParams = new Dictionary < string , object >
{
{ "campaign_id" , "SUMMER2025" },
{ "ad_group" , "electronics" }
};
AdStage. TrackEvent (AdStageEvent. Click (clickParams));
AdStage Unity SDK provides 46 standard events.
// 1. Ad click
AdStage. TrackEvent (AdStageEvent. Click (
new Dictionary < string , object > { { "campaign_id" , "CAMP_123" } }
));
// 2. Ad impression
AdStage. TrackEvent (AdStageEvent. View (
new Dictionary < string , object > { { "impression_id" , "IMP_456" } }
));
// 3. App install
AdStage. TrackEvent (AdStageEvent. Install ());
// 4. Custom event (specify event name with event_name)
AdStage. TrackEvent (AdStageEvent. Custom (
new Dictionary < string , object > {
{ "event_name" , "promotion_click" },
{ "promotion_id" , "summer_sale_2025" }
}
));
// 1. Sign up complete
AdStage. TrackEvent (AdStageEvent. SignUp ( method : "google" ));
// 2. Sign up start
AdStage. TrackEvent (AdStageEvent. SignUpStart ());
// 3. Login
AdStage. TrackEvent (AdStageEvent. Login ( method : "email" ));
// 4. Logout
AdStage. TrackEvent (AdStageEvent. Logout ());
// 5. First app open
AdStage. TrackEvent (AdStageEvent. FirstOpen ());
// 1. Home screen
AdStage. TrackEvent (AdStageEvent. HomeView ());
// 2. Product list
AdStage. TrackEvent (AdStageEvent. ProductListView ( itemCategory : "electronics" ));
// 3. Search results
AdStage. TrackEvent (AdStageEvent. SearchResultView ( searchTerm : "wireless headphones" ));
// 4. Product details
AdStage. TrackEvent (AdStageEvent. ProductDetailsView (
itemId : "PROD_123" ,
itemName : "Wireless Earbuds"
));
// 5. Page view (Web)
AdStage. TrackEvent (AdStageEvent. PageView (
pageUrl : "https://example.com/products" ,
pageTitle : "Products"
));
// 6. Screen view (Unity Scene)
AdStage. TrackEvent (AdStageEvent. ScreenView (
screenName : "MainMenu" ,
screenClass : "MainMenuScene"
));
// 1. Add to cart
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. Remove from cart
AdStage. TrackEvent (AdStageEvent. RemoveFromCart (
value : 50000.0 ,
currency : "KRW"
));
// 3. Add to wishlist
AdStage. TrackEvent (AdStageEvent. AddToWishlist (
itemId : "PROD_456" ,
itemName : "Smart Watch"
));
// 4. Add payment info
AdStage. TrackEvent (AdStageEvent. AddPaymentInfo ( paymentType : "credit_card" ));
// 5. Begin checkout
AdStage. TrackEvent (AdStageEvent. BeginCheckout (
value : 150000.0 ,
currency : "KRW"
));
// 6. Purchase complete ⭐⭐⭐
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. Refund
AdStage. TrackEvent (AdStageEvent. Refund (
transactionId : "ORDER_20250105_001" ,
value : 129000.0 ,
currency : "KRW"
));
// 1. Tutorial begin
AdStage. TrackEvent (AdStageEvent. TutorialBegin (
new Dictionary < string , object > { { "tutorial_id" , "intro" } }
));
// 2. Tutorial complete
AdStage. TrackEvent (AdStageEvent. TutorialComplete (
new Dictionary < string , object > { { "duration_seconds" , 120 } }
));
// 3. Level up
AdStage. TrackEvent (AdStageEvent. LevelUp (
level : 25 ,
character : "warrior"
));
// 4. Achievement
AdStage. TrackEvent (AdStageEvent. Achievement ( achievementId : "first_win" ));
// 1. Search
AdStage. TrackEvent (AdStageEvent. Search ( searchTerm : "gaming laptop" ));
// 2. Share
AdStage. TrackEvent (AdStageEvent. Share (
contentType : "product" ,
itemId : "PROD_789" ,
method : "kakao"
));
// 3. Ad click
AdStage. TrackEvent (AdStageEvent. AdClick ( adPlatform : "unity" , adSource : "unity_source" , adFormat : "unity_format" , adUnitName : "AD_12345" ));
// 1. Game play
AdStage. TrackEvent (AdStageEvent. GamePlay (
level : 10 ,
levelName : "Dragon's Lair" ,
character : "mage" ,
contentType : "dungeon"
));
// 2. Acquire bonus
AdStage. TrackEvent (AdStageEvent. AcquireBonus (
contentType : "reward" ,
itemId : "ITEM_123" ,
itemName : "Gold Chest" ,
quantity : 1
));
// 3. Select game server
AdStage. TrackEvent (AdStageEvent. SelectGameServer (
contentId : "SERVER_01" ,
contentType : "pvp" ,
itemName : "Asia Server"
));
// 4. Complete patch
AdStage. TrackEvent (AdStageEvent. CompletePatch (
contentId : "PATCH_2.1.0" ,
contentType : "update"
));
// 1. Start trial
AdStage. TrackEvent (AdStageEvent. StartTrial (
value : 9900.0 ,
currency : "KRW" ,
trialDays : 14
));
// 2. Subscribe
AdStage. TrackEvent (AdStageEvent. Subscribe (
value : 9900.0 ,
currency : "KRW" ,
subscriptionId : "premium_monthly"
));
// 3. Unsubscribe
AdStage. TrackEvent (AdStageEvent. Unsubscribe ( subscriptionId : "premium_monthly" ));
This is normal behavior! Editor only outputs logs, actual sending doesn't occur.
Verification:
# if UNITY_EDITOR
Debug. Log ( "📊 [Editor Mode] Events are only sent on actual devices" );
# endif
Checklist:
Check Logcat : adb logcat | grep -i adstage
Internet Permission : Verify INTERNET permission in AndroidManifest.xml
Disable Minify (for testing): Check ProGuard/R8 settings
// Test with debug build
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;
Checklist:
Check Xcode Console : Verify error messages
Framework Linking : Verify AdapterAdStage.framework embed
Bitcode Settings : Disable Bitcode in Build Settings
Solution:
// Create link.xml file
< linker >
< assembly fullname = "AdStageSDK" preserve = "all" />
< assembly fullname = "AdStageSDK.Models" preserve = "all" />
</ linker >
Issue:
System.ArgumentException: Invalid JSON
Solution:
// Check if Dictionary values are null
var parameters = new Dictionary < string , object >
{
{ "key1" , value ?? "default" },
{ "key2" , string . IsNullOrEmpty (value2) ? "unknown" : value2 }
};
// ❌ 2-letter code
AdStageEvent. Purchase ( value : 100.0 , currency : "KR" )
// ValidationException: "Currency must be 3-letter ISO 4217 code"
// ✅ 3-letter ISO 4217 code
AdStageEvent. Purchase ( value : 100.0 , currency : "KRW" ) // Korean Won
AdStageEvent. Purchase ( value : 100.0 , currency : "USD" ) // US Dollar
AdStageEvent. Purchase ( value : 100.0 , currency : "JPY" ) // Japanese Yen
Q: Can I test in Unity Editor?
A: Editor only outputs logs. Actual testing must be done on devices.
Q: Does it work the same on Android and iOS?
A: Yes, all 46 events work identically.
Q: Can I use it with Unity IAP?
A: Yes, call AdStage events in the ProcessPurchase callback.
Q: Does it work offline?
A: Yes, the native SDK automatically queues events and sends them when network is restored.
Q: How do I send custom events?
A: Use AdStageEvent.Custom(new Dictionary<string, object> {...})
Contact:
© 2025 NBase. All rights reserved.