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 Android/iOS native SDKs.

Supported Platforms

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

Basic Setup

1. Package Installation

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

2. SDK Initialization

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

3. Android Setup (AndroidManifest.xml)

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

4. iOS Setup (Info.plist)

<!-- Network usage permission -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
</dict>

Type-Safe Event Tracking

1. Simplest Approach

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

2. Purchase Event (Validation Example)

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

3. Using Callbacks

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

4. Custom Events (event_name Auto-Promotion)

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

Standard Event Catalog

AdStage Unity SDK provides 46 standard events.

📌 Ad Tracking (4 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" }
    }
));

👤 User Lifecycle (5 events)

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

📄 Content Views (6 events)

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

🛒 E-commerce (8 events)

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

🎮 Progress/Achievement (4 events)

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

💬 Interactions (3 events)

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

🎮 Game-Specific (4 events)

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

📅 Subscription/Trial (3 events)

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

Troubleshooting

1. Events Not Sent in Unity Editor

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

2. Events Not Sent After Android Build

Checklist:

  1. Check Logcat: adb logcat | grep -i adstage
  2. Internet Permission: Verify INTERNET permission in AndroidManifest.xml
  3. Disable Minify (for testing): Check ProGuard/R8 settings
// Test with debug build
BuildOptions options = BuildOptions.Development | BuildOptions.AllowDebugging;

3. Events Not Sent After iOS Build

Checklist:

  1. Check Xcode Console: Verify error messages
  2. Framework Linking: Verify AdapterAdStage.framework embed
  3. Bitcode Settings: Disable Bitcode in Build Settings

4. IL2CPP Build Error

Solution:

// Create link.xml file
<linker>
    <assembly fullname="AdStageSDK" preserve="all"/>
    <assembly fullname="AdStageSDK.Models" preserve="all"/>
</linker>

5. JSON Serialization Error

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

6. Currency Code Validation Error

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

References

Standards


FAQ

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


Support

Contact:


© 2025 NBase. All rights reserved.

Table of Contents