Migrate from v3.x to v6.0.0
BlueStack Unity SDK v6.0.0 is a major release. The native dependencies have moved to the v6 generation of the BlueStack Core SDK, and a number of public C# APIs have been renamed or have shape changes for naming consistency across ad formats.
This guide walks you through the changes you will need to apply to an existing v3.x integration to make it compile and run on v6.0.0.
Full per-version notes live in the Release Notes. This page focuses on the mechanical changes a v3.x consumer needs to make.
At a glance
| Area | What changed | Required action |
|---|---|---|
| Package version | com.azerion.bluestack bumped to 6.0.0 | Update Packages/manifest.json |
| Native dependencies | Core SDK + mediation adapters bumped to v6.0.x | Force-resolve EDM4U (Android) and run pod install (iOS) after upgrade |
BlueStackAds.Initialize | Signature simplified; Settings and split init callbacks removed | Switch to SetDebugMode(bool) + single-callback Initialize |
RewardedVideoAd | Class renamed to RewardedAd | Rename class references |
| Reward event | OnUserRewardEarned → OnAdRewardEarned | Rename subscription |
| Banner events | Renamed to the unified OnAd* convention | Rename subscriptions (see table) |
Banner OnAdLoaded payload | Now carries PreferredBannerSize | Update handler signature |
| Interstitial events | Renamed to the unified OnAd* convention | Rename subscriptions (see table) |
| Rewarded events | Renamed to the unified OnAd* convention | Rename subscriptions (see table) |
| Banner with mask | Masked constructor removed | Construct normally, then call SetMask(RectTransform, Camera) |
Step 1 — Bump the package version
Update Packages/manifest.json:
{
"dependencies": {
"com.azerion.bluestack": "6.0.0"
}
}
After Unity refreshes the package, force-resolve native dependencies:
- Android
- iOS
Assets > External Dependency Manager > Android Resolver > Force Resolve
The resolved AAR dependency line in Assets/Plugins/Android/mainTemplate.gradle should now read:
implementation 'com.azerion:bluestack-sdk-core:6.0.1'
After the next Unity iOS export, run pod install --repo-update in the exported Xcode project to
pull the new BlueStack-SDK v6 pod and mediation adapters.
Step 2 — Update SDK initialization
The v3.x Initialize carried a Settings snapshot and two separate callbacks
(SDKInitializationStatus, AdaptersInitializationStatus). In v6.0.0 the Settings argument is gone,
the debug-mode toggle has its own setter, and a single Initialize callback delivers the
per-adapter InitializationStatus.
Before (v3.x)
using Azerion.BlueStack.API;
public class BlueStackAdController : MonoBehaviour
{
public void Start()
{
Settings settings = new Settings(isDebugModeEnabled: true);
BlueStackAds.Initialize(appId, settings,
HandleSDKInitCompleteAction,
HandleAdaptersInitCompleteAction);
}
private void HandleSDKInitCompleteAction(SDKInitializationStatus sdkInitializationStatus)
{
Debug.Log("SDK init: " + sdkInitializationStatus.IsSuccess);
}
private void HandleAdaptersInitCompleteAction(AdaptersInitializationStatus adaptersStatus)
{
foreach (var kv in adaptersStatus.GetAdapterStatusMap())
{
Debug.Log($"Adapter {kv.Key}: {kv.Value.InitializationState}");
}
}
}
After (v6.0.0)
using Azerion.BlueStack.API;
public class BlueStackAdController : MonoBehaviour
{
public void Start()
{
// Toggle native SDK debug logging at any time.
BlueStackAds.SetDebugMode(true);
BlueStackAds.Initialize(appId, HandleInitializationComplete);
}
// Single callback. Runs on the Unity main thread on both iOS and Android in v6.0.0.
private void HandleInitializationComplete(InitializationStatus status)
{
foreach (var kv in status.AdapterStatusMap)
{
Debug.Log($"Adapter {kv.Key}: {kv.Value.InitializationState} ({kv.Value.Description})");
}
// Readiness can now also be checked synchronously at any time:
if (BlueStackAds.IsInitialized)
{
Debug.Log("BlueStack SDK is ready to load ads.");
}
}
}
Notes:
Settingsis gone — the class is retained for source compatibility only and is no longer consulted by the SDK. Delete anynew Settings(...)constructions in your code.- No more "SDK init success/fail" event — if you previously branched on
SDKInitializationStatus.IsSuccess, instead inspectstatus.AdapterStatusMapto check which adapters reachedAdapterState.Ready. - Main-thread guarantee — v6.0.0 dispatches the init callback to Unity's main thread on both iOS and Android. You no longer need to marshal it yourself before touching UnityEngine APIs.
Step 3 — Rename RewardedVideoAd to RewardedAd
The class was renamed for naming parity with BannerAd / InterstitialAd. The file name in your
project also changes (you reference it as RewardedAd everywhere now).
Before
private RewardedVideoAd _rewardedVideoAd;
_rewardedVideoAd = new RewardedVideoAd(placementId);
_rewardedVideoAd.OnUserRewardEarned += (sender, item) =>
{
Debug.Log($"Reward: {item.Amount} {item.Type}");
};
_rewardedVideoAd.Load();
After
private RewardedAd _rewardedAd;
_rewardedAd = new RewardedAd(placementId);
_rewardedAd.OnAdRewardEarned += (sender, item) =>
{
Debug.Log($"Reward: {item.Amount} {item.Type}");
};
_rewardedAd.Load();
Step 4 — Rename ad events
Events on all three full-screen formats now follow the unified OnAdXxx convention, matching
what the native BlueStack SDK delivers internally.
Banner
| v3.x | v6.0.0 | Payload |
|---|---|---|
OnBannerDidLoad | OnAdLoaded | PreferredBannerSize (was EventArgs) |
OnBannerDidFailed | OnAdFailedToLoad | BlueStackError |
OnBannerDisplay | OnAdDisplayed | EventArgs |
OnBannerHide | OnAdHidden | EventArgs |
OnAdClicked | OnAdClicked | EventArgs |
OnBannerDidRefresh | OnAdRefreshed | EventArgs |
OnBannerDidFailToRefresh | OnAdFailedToRefresh | BlueStackError |
| (new) | OnAdResized | PreferredBannerSize |
The OnAdLoaded payload type changed — your handler now receives the SDK-preferred banner size:
// v3.x
_bannerAd.OnBannerDidLoad += (sender, args) =>
{
_bannerAd.Show();
};
// v6.0.0
_bannerAd.OnAdLoaded += (sender, size) =>
{
Debug.Log($"Loaded banner preferred size: {size.Width}x{size.Height}");
_bannerAd.Show();
};
The new OnAdResized event lets you react when a refresh delivers a creative of a different size
(useful for DynamicBanner / DynamicLeaderboard):
_bannerAd.OnAdResized += (sender, size) =>
{
Debug.Log($"Banner resized: {size.Width}x{size.Height}");
};
Interstitial
| v3.x | v6.0.0 | Payload |
|---|---|---|
OnInterstitialDidLoaded | OnAdLoaded | EventArgs |
OnInterstitialDidFail | OnAdFailedToLoad | BlueStackError |
OnInterstitialClicked | OnAdClicked | EventArgs |
OnInterstitialDidShown | OnAdDisplayed | EventArgs |
OnInterstitialDisappear | OnAdDismissed | EventArgs |
| (new) | OnAdFailedToDisplay | BlueStackError |
Rewarded
| v3.x | v6.0.0 | Payload |
|---|---|---|
OnRewardedVideoAdLoaded | OnAdLoaded | EventArgs |
OnRewardedVideoAdError | OnAdFailedToLoad | BlueStackError |
OnRewardedVideoAdAppeared | OnAdDisplayed | EventArgs |
OnRewardedVideoAdClicked | OnAdClicked | EventArgs |
OnRewardedVideoAdClosed | OnAdDismissed | EventArgs |
OnUserRewardEarned | OnAdRewardEarned | RewardedItem |
| (new) | OnAdFailedToDisplay | BlueStackError |
A project-wide find-and-replace covers most of the work — the unified OnAd* names do not collide
between formats since each handler is bound to a specific ad instance.
Step 5 — Verify the build
- Editor: re-open the project. Compilation errors will surface every remaining v3.x identifier; work through them top-down.
- Android: build a debug APK. Force-resolve Android dependencies first
(
Assets > External Dependency Manager > Android Resolver > Force Resolve). - iOS: export the Xcode project. Delete the
Pods/andPodfile.lockfrom previous v3.x exports if present, then runpod install --repo-update.
After a v3.x → v6.0.0 upgrade, do a clean build of the player. Stale managed assemblies referencing the old class / event names can mask compilation errors until they're flushed.
Recommended v6.0.0 features to adopt
These additions are optional but generally simplify common integrations.
IsReady for full-screen ads
Both InterstitialAd and RewardedAd expose an IsReady property:
if (_interstitialAd.IsReady) _interstitialAd.Show();
if (_rewardedAd.IsReady) _rewardedAd.Show();
This lets you gate Show() from a button click without having to wire up OnAdLoaded callback
state-tracking yourself.
Anchored banner positioning
If you want a banner to follow a UI / world-space GameObject, use the anchor-based constructor —
the SDK adds an AdPlacementHandler component that tracks anchor.position automatically:
_bannerAd = new BannerAd(placementId, anchorTransform, trackingCamera);
Use bannerAd.PlacementHandler.UpdateInterval = 0.1f to throttle anchor tracking
(clamped to [0, 5] seconds; default is every frame).
useSafeArea opt-out
For sticky Top/Bottom banners, pass useSafeArea: false to overlap the notch / home indicator /
status bar:
_bannerAd = new BannerAd(placementId, AdPosition.Bottom, useSafeArea: false);
Custom-positioned banners (Vector2 or Transform anchor) always ignore the safe area regardless
of this flag.
Mask UpdateInterval throttling
If a mask is bound to a heavily animated RectTransform, throttle native updates:
_bannerAd.SetMask(maskRect);
_bannerAd.MaskHandler.UpdateInterval = 0.1f; // 10 Hz
Removed APIs reference
If you see compile errors for any of the following symbols, refer to the section linked alongside.
| Removed | Replacement | Section |
|---|---|---|
Settings(bool) argument to Initialize | BlueStackAds.SetDebugMode(bool) | Step 2 |
Action<SDKInitializationStatus> init callback | Action<InitializationStatus> (single callback) | Step 2 |
Action<IInitializationStatusClient> adapters callback | Folded into the single Action<InitializationStatus> | Step 2 |
class RewardedVideoAd | class RewardedAd | Step 3 |
RewardedAd.OnUserRewardEarned | RewardedAd.OnAdRewardEarned | Step 3 |
BannerAd.OnBannerDidLoad and family | BannerAd.OnAd* | Step 4 — Banner |
InterstitialAd.OnInterstitial* | InterstitialAd.OnAd* | Step 4 — Interstitial |
RewardedAd.OnRewardedVideoAd* | RewardedAd.OnAd* | Step 4 — Rewarded |
BannerAd(string, Transform, RectTransform, Camera) | Anchor ctor + SetMask(RectTransform, Camera) | Step 5 |