Unity WebGL Integration
Integrate BZZE Ads into your Unity game exported to WebGL using JavaScript interop. Call the SDK from C# scripts.
How It Works
Unity WebGL can communicate with JavaScript using:
- Application.ExternalCall() - Call JavaScript from C#
- Application.ExternalEval() - Execute JavaScript code
- [DllImport("__Internal")] - Import JavaScript functions as C# methods
We'll use this to bridge Unity C# ↔ BZZE Ads JavaScript SDK.
Quick Setup
Step 1: Modify WebGL Template
After building your Unity WebGL project, edit the generated index.html:
<!-- Load BZZE Ads SDK -->
<script src="https://ads.bzze.com/sdk/rewarded.min.js"></script>
<script>
// Initialize BZZE Ads after Unity loads
window.addEventListener('load', function() {
setTimeout(function() {
window.RewardedAd.init({
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_API_KEY',
userId: 'user_' + Date.now(),
autoPreload: true,
onReward: function(reward) {
// Call Unity C# method
if (typeof unityInstance !== 'undefined') {
unityInstance.SendMessage('BZZEAdsManager', 'OnAdRewardEarned', '');
}
},
onAdLoaded: function(count) {
if (typeof unityInstance !== 'undefined') {
unityInstance.SendMessage('BZZEAdsManager', 'OnAdsLoaded', count.toString());
}
},
onNoFill: function() {
if (typeof unityInstance !== 'undefined') {
unityInstance.SendMessage('BZZEAdsManager', 'OnNoFill', '');
}
},
onError: function(error) {
if (typeof unityInstance !== 'undefined') {
unityInstance.SendMessage('BZZEAdsManager', 'OnAdError', error.message);
}
}
});
}, 1000);
});
// Expose functions for Unity to call
window.ShowBZZEAd = function(rewardPreview, placement) {
if (window.RewardedAd) {
window.RewardedAd.showAd({
rewardPreview: rewardPreview || '',
placement: placement || 'default'
});
}
};
window.IsBZZEAdAvailable = function() {
return window.RewardedAd ? window.RewardedAd.isAdAvailable() : false;
};
</script>
Step 2: Create C# Manager Script
Create Assets/Scripts/BZZEAdsManager.cs:
using UnityEngine;
using System.Runtime.InteropServices;
public class BZZEAdsManager : MonoBehaviour
{
// Events
public delegate void AdRewardEarnedHandler();
public static event AdRewardEarnedHandler OnRewardEarned;
public delegate void AdsLoadedHandler(int count);
public static event AdsLoadedHandler OnAdsAvailable;
public delegate void NoFillHandler();
public static event NoFillHandler OnAdNoFill;
public delegate void ErrorHandler(string message);
public static event ErrorHandler OnAdErrorOccurred;
// Import JavaScript functions
[DllImport("__Internal")]
private static extern void ShowBZZEAd(string rewardPreview, string placement);
[DllImport("__Internal")]
private static extern bool IsBZZEAdAvailable();
private static BZZEAdsManager instance;
void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
gameObject.name = "BZZEAdsManager"; // Important: must match SendMessage name
}
else
{
Destroy(gameObject);
}
}
// Call this from Unity to show an ad
public static void ShowAd(string rewardPreview = "", string placement = "default")
{
#if UNITY_WEBGL && !UNITY_EDITOR
ShowBZZEAd(rewardPreview, placement);
#else
Debug.Log("BZZE Ads: ShowAd() called (WebGL only)");
#endif
}
// Check if ads are available
public static bool IsAdAvailable()
{
#if UNITY_WEBGL && !UNITY_EDITOR
return IsBZZEAdAvailable();
#else
return false;
#endif
}
// Called from JavaScript when reward earned
public void OnAdRewardEarned(string data)
{
Debug.Log("BZZE Ads: Reward earned!");
OnRewardEarned?.Invoke();
}
// Called from JavaScript when ads loaded
public void OnAdsLoaded(string countStr)
{
int count = int.Parse(countStr);
Debug.Log($"BZZE Ads: {count} ads loaded");
OnAdsAvailable?.Invoke(count);
}
// Called from JavaScript when no ads
public void OnNoFill(string data)
{
Debug.Log("BZZE Ads: No ads available");
OnAdNoFill?.Invoke();
}
// Called from JavaScript on error
public void OnAdError(string message)
{
Debug.LogError($"BZZE Ads Error: {message}");
OnAdErrorOccurred?.Invoke(message);
}
}
Step 3: Create Plugin File (Optional but Recommended)
Create Assets/Plugins/BZZEAds.jslib:
mergeInto(LibraryManager.library, {
ShowBZZEAd: function(rewardPreviewPtr, placementPtr) {
var rewardPreview = UTF8ToString(rewardPreviewPtr);
var placement = UTF8ToString(placementPtr);
if (window.ShowBZZEAd) {
window.ShowBZZEAd(rewardPreview, placement);
}
},
IsBZZEAdAvailable: function() {
if (window.IsBZZEAdAvailable) {
return window.IsBZZEAdAvailable() ? 1 : 0;
}
return 0;
}
});
Step 4: Use in Your Game Scripts
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public Text coinsText;
public Button watchAdButton;
private int coins = 0;
void Start()
{
// Subscribe to ad events
BZZEAdsManager.OnRewardEarned += HandleAdReward;
BZZEAdsManager.OnAdsAvailable += HandleAdsLoaded;
BZZEAdsManager.OnAdNoFill += HandleNoFill;
// Set up button
watchAdButton.onClick.AddListener(ShowRewardedAd);
// Check ad availability every 2 seconds
InvokeRepeating("UpdateAdButton", 0f, 2f);
UpdateUI();
}
void OnDestroy()
{
// Unsubscribe
BZZEAdsManager.OnRewardEarned -= HandleAdReward;
BZZEAdsManager.OnAdsAvailable -= HandleAdsLoaded;
BZZEAdsManager.OnAdNoFill -= HandleNoFill;
}
void ShowRewardedAd()
{
// Show ad
BZZEAdsManager.ShowAd("100 coins", "main_menu");
}
void HandleAdReward()
{
// Grant reward
coins += 100;
UpdateUI();
// Show success message
Debug.Log("You earned 100 coins!");
}
void HandleAdsLoaded(int count)
{
Debug.Log($"{count} ads are ready");
}
void HandleNoFill()
{
Debug.Log("No ads available right now");
}
void UpdateAdButton()
{
watchAdButton.interactable = BZZEAdsManager.IsAdAvailable();
}
void UpdateUI()
{
coinsText.text = $"Coins: {coins}";
}
}
Complete Example
Here's a full game manager with multiple reward types:
using UnityEngine;
using UnityEngine.UI;
public class CompleteGameManager : MonoBehaviour
{
[Header("UI Elements")]
public Text coinsText;
public Text livesText;
public Button watchAdForCoinsButton;
public Button watchAdForLifeButton;
[Header("Game State")]
private int coins = 0;
private int lives = 3;
private string currentRewardType = "";
void Start()
{
// Subscribe to events
BZZEAdsManager.OnRewardEarned += OnAdRewardEarned;
BZZEAdsManager.OnAdNoFill += OnAdNoFill;
BZZEAdsManager.OnAdErrorOccurred += OnAdError;
// Set up buttons
watchAdForCoinsButton.onClick.AddListener(WatchAdForCoins);
watchAdForLifeButton.onClick.AddListener(WatchAdForLife);
// Update button states
InvokeRepeating("UpdateButtonStates", 0f, 2f);
UpdateUI();
}
void OnDestroy()
{
BZZEAdsManager.OnRewardEarned -= OnAdRewardEarned;
BZZEAdsManager.OnAdNoFill -= OnAdNoFill;
BZZEAdsManager.OnAdErrorOccurred -= OnAdError;
}
void WatchAdForCoins()
{
currentRewardType = "coins";
BZZEAdsManager.ShowAd("100 coins", "menu_coins");
}
void WatchAdForLife()
{
currentRewardType = "life";
BZZEAdsManager.ShowAd("1 extra life", "menu_life");
}
void OnAdRewardEarned()
{
switch (currentRewardType)
{
case "coins":
coins += 100;
ShowMessage("You earned 100 coins!");
break;
case "life":
lives += 1;
ShowMessage("You earned 1 extra life!");
break;
}
currentRewardType = "";
UpdateUI();
}
void OnAdNoFill()
{
ShowMessage("No ads available right now");
}
void OnAdError(string message)
{
ShowMessage($"Error: {message}");
}
void UpdateButtonStates()
{
bool adsAvailable = BZZEAdsManager.IsAdAvailable();
watchAdForCoinsButton.interactable = adsAvailable;
watchAdForLifeButton.interactable = adsAvailable;
}
void UpdateUI()
{
coinsText.text = $"💰 Coins: {coins}";
livesText.text = $"❤️ Lives: {lives}";
}
void ShowMessage(string message)
{
Debug.Log(message);
// Show UI message to player
}
// Call this when player dies
public void OnGameOver()
{
// Show continue with ad option
currentRewardType = "continue";
// Show UI asking if player wants to watch ad to continue
}
}
Best Practices
1. Use DontDestroyOnLoad
Keep BZZEAdsManager alive across scenes:
void Awake()
{
DontDestroyOnLoad(gameObject);
}
2. Pause Game During Ads
void ShowAd()
{
// Pause game
Time.timeScale = 0;
AudioListener.pause = true;
// Show ad
BZZEAdsManager.ShowAd("100 coins");
}
void OnAdRewardEarned()
{
// Resume game
Time.timeScale = 1;
AudioListener.pause = false;
// Grant reward
GrantReward();
}
3. Test in Editor with Mocks
public static void ShowAd(string rewardPreview = "", string placement = "default")
{
#if UNITY_WEBGL && !UNITY_EDITOR
ShowBZZEAd(rewardPreview, placement);
#else
// Mock behavior in editor
Debug.Log($"[Mock] Showing ad: {rewardPreview}");
if (instance != null)
{
instance.StartCoroutine(MockAdReward());
}
#endif
}
#if UNITY_EDITOR
private System.Collections.IEnumerator MockAdReward()
{
yield return new WaitForSeconds(2f);
OnRewardEarned?.Invoke();
}
#endif
Custom WebGL Template (Advanced)
To avoid editing index.html after every build:
- Copy Unity's default WebGL template from
Unity/PlaybackEngines/WebGLSupport/BuildTools/WebGLTemplates/Default - Paste into
Assets/WebGLTemplates/BZZEAds - Edit
index.htmlin that folder to include BZZE Ads SDK - In Unity: Player Settings → Resolution and Presentation → WebGL Template → BZZEAds
Now every build will include BZZE Ads automatically!
Troubleshooting
SendMessage not working
Problem: Unity doesn't receive JavaScript callbacks
Solution: Make sure GameObject name matches exactly: gameObject.name = "BZZEAdsManager";
DllImport error
Problem: DllNotFoundException: __Internal
Solution: This is expected in Editor. Wrap calls in #if UNITY_WEBGL && !UNITY_EDITOR
Ads not showing
Problem: No ads appear in WebGL build
Solution: Check browser console (F12) for errors. Make sure index.html was modified correctly.