广告测试

This commit is contained in:
2026-06-02 17:51:10 +08:00
parent 6866b7fca9
commit 4f33446770
9 changed files with 5138 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
public static class AdReadyStateLog
{
public static string FormatReadyCheck(string format, string adUnitId, bool isReady)
{
string status = isReady ? "OK" : "WARNING";
return $"[{format}] Loaded callback ready check: adUnitId={adUnitId}, IsReady={isReady}, {status}";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6db64ebff4c74a8e987935dcdf9fd211
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AdTest : MonoBehaviour
{
[Header("Rewarded")]
[SerializeField] private string androidRewardedAdUnitId = "c6c49a100de8496c";
[SerializeField] private string iosRewardedAdUnitId = "ec3c8fd688cdb5e2";
[Header("Interstitial")]
[SerializeField] private string androidInterstitialAdUnitId = "0dcd37fa0885aa1f";
[SerializeField] private string iosInterstitialAdUnitId = "interstitial_test_ios";
[Header("UI")]
[SerializeField] private Button initMaxButton;
[SerializeField] private Button loadRewardedButton;
[SerializeField] private Button showRewardedButton;
[SerializeField] private Button forceShowRewardedButton;
[SerializeField] private Button checkRewardedReadyButton;
[SerializeField] private Button loadInterstitialButton;
[SerializeField] private Button showInterstitialButton;
[SerializeField] private Button forceShowInterstitialButton;
[SerializeField] private Button checkInterstitialReadyButton;
[SerializeField] private Button mediationDebuggerButton;
[SerializeField] private Button clearLogButton;
[SerializeField] private Text logText;
private const int MaxLogLines = 80;
private readonly List<string> logLines = new List<string>();
private bool callbacksRegistered;
private bool sdkInitializeRequested;
private int rewardedLoadFailCount;
private int interstitialLoadFailCount;
private string RewardedAdUnitId
{
get
{
#if UNITY_IOS
return iosRewardedAdUnitId;
#else
return androidRewardedAdUnitId;
#endif
}
}
private string InterstitialAdUnitId
{
get
{
#if UNITY_IOS
return iosInterstitialAdUnitId;
#else
return androidInterstitialAdUnitId;
#endif
}
}
public void Configure(
Button initMax,
Button loadRewarded,
Button showRewarded,
Button forceShowRewarded,
Button checkRewardedReady,
Button loadInterstitial,
Button showInterstitial,
Button forceShowInterstitial,
Button checkInterstitialReady,
Button mediationDebugger,
Button clearLog,
Text output)
{
initMaxButton = initMax;
loadRewardedButton = loadRewarded;
showRewardedButton = showRewarded;
forceShowRewardedButton = forceShowRewarded;
checkRewardedReadyButton = checkRewardedReady;
loadInterstitialButton = loadInterstitial;
showInterstitialButton = showInterstitial;
forceShowInterstitialButton = forceShowInterstitial;
checkInterstitialReadyButton = checkInterstitialReady;
mediationDebuggerButton = mediationDebugger;
clearLogButton = clearLog;
logText = output;
}
private void Start()
{
Bind(initMaxButton, InitMax);
Bind(loadRewardedButton, LoadRewarded);
Bind(showRewardedButton, ShowRewarded);
Bind(forceShowRewardedButton, ForceShowRewarded);
Bind(checkRewardedReadyButton, CheckRewardedReady);
Bind(loadInterstitialButton, LoadInterstitial);
Bind(showInterstitialButton, ShowInterstitial);
Bind(forceShowInterstitialButton, ForceShowInterstitial);
Bind(checkInterstitialReadyButton, CheckInterstitialReady);
Bind(mediationDebuggerButton, ShowMediationDebugger);
Bind(clearLogButton, ClearLog);
AppendLog("AdTest ready.");
}
private void OnDestroy()
{
if (!callbacksRegistered)
{
return;
}
MaxSdkCallbacks.OnSdkInitializedEvent -= OnSdkInitialized;
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent -= OnRewardedAdLoaded;
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent -= OnRewardedAdLoadFailed;
MaxSdkCallbacks.Rewarded.OnAdDisplayedEvent -= OnRewardedAdDisplayed;
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent -= OnRewardedAdDisplayFailed;
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent -= OnRewardedAdHidden;
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent -= OnRewardedAdReceivedReward;
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent -= OnRewardedAdRevenuePaid;
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent -= OnInterstitialAdLoaded;
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent -= OnInterstitialAdLoadFailed;
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent -= OnInterstitialAdDisplayed;
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent -= OnInterstitialAdDisplayFailed;
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent -= OnInterstitialAdHidden;
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent -= OnInterstitialAdRevenuePaid;
}
private void Bind(Button button, Action action)
{
if (button == null)
{
return;
}
button.onClick.AddListener(() => action());
}
public void InitMax()
{
RegisterCallbacks();
if (sdkInitializeRequested)
{
AppendLog("MAX initialization already requested.");
return;
}
sdkInitializeRequested = true;
MaxSdk.SetHasUserConsent(true);
MaxSdk.SetDoNotSell(false);
MaxSdk.InitializeSdk();
AppendLog("MAX initialization requested.");
}
public void LoadRewarded()
{
EnsureInitialized();
AppendLog($"Load rewarded: {RewardedAdUnitId}");
MaxSdk.LoadRewardedAd(RewardedAdUnitId);
}
public void ShowRewarded()
{
EnsureInitialized();
bool isReady = MaxSdk.IsRewardedAdReady(RewardedAdUnitId);
AppendLog($"Show rewarded requested. IsReady={isReady}");
if (isReady)
{
MaxSdk.ShowRewardedAd(RewardedAdUnitId);
return;
}
LoadRewarded();
}
public void ForceShowRewarded()
{
EnsureInitialized();
AppendLog($"Force show rewarded without ready check: {RewardedAdUnitId}");
MaxSdk.ShowRewardedAd(RewardedAdUnitId);
}
public void CheckRewardedReady()
{
EnsureInitialized();
bool isReady = MaxSdk.IsRewardedAdReady(RewardedAdUnitId);
AppendReadyCheck("Rewarded", RewardedAdUnitId, isReady);
}
public void LoadInterstitial()
{
EnsureInitialized();
if (string.IsNullOrEmpty(InterstitialAdUnitId))
{
AppendWarning("Interstitial ad unit ID is empty.");
return;
}
AppendLog($"Load interstitial: {InterstitialAdUnitId}");
MaxSdk.LoadInterstitial(InterstitialAdUnitId);
}
public void ShowInterstitial()
{
EnsureInitialized();
if (string.IsNullOrEmpty(InterstitialAdUnitId))
{
AppendWarning("Interstitial ad unit ID is empty.");
return;
}
bool isReady = MaxSdk.IsInterstitialReady(InterstitialAdUnitId);
AppendLog($"Show interstitial requested. IsReady={isReady}");
if (isReady)
{
MaxSdk.ShowInterstitial(InterstitialAdUnitId);
return;
}
LoadInterstitial();
}
public void ForceShowInterstitial()
{
EnsureInitialized();
if (string.IsNullOrEmpty(InterstitialAdUnitId))
{
AppendWarning("Interstitial ad unit ID is empty.");
return;
}
AppendLog($"Force show interstitial without ready check: {InterstitialAdUnitId}");
MaxSdk.ShowInterstitial(InterstitialAdUnitId);
}
public void CheckInterstitialReady()
{
EnsureInitialized();
if (string.IsNullOrEmpty(InterstitialAdUnitId))
{
AppendWarning("Interstitial ad unit ID is empty.");
return;
}
bool isReady = MaxSdk.IsInterstitialReady(InterstitialAdUnitId);
AppendReadyCheck("Interstitial", InterstitialAdUnitId, isReady);
}
public void ClearLog()
{
logLines.Clear();
if (logText != null)
{
logText.text = string.Empty;
}
}
public void ShowMediationDebugger()
{
AppendLog("Show mediation debugger requested.");
MaxSdk.ShowMediationDebugger();
}
private void EnsureInitialized()
{
if (!sdkInitializeRequested)
{
InitMax();
}
}
private void RegisterCallbacks()
{
if (callbacksRegistered)
{
return;
}
callbacksRegistered = true;
MaxSdkCallbacks.OnSdkInitializedEvent += OnSdkInitialized;
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoaded;
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdLoadFailed;
MaxSdkCallbacks.Rewarded.OnAdDisplayedEvent += OnRewardedAdDisplayed;
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent += OnRewardedAdDisplayFailed;
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdHidden;
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedReward;
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdRevenuePaid;
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialAdLoaded;
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialAdLoadFailed;
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialAdDisplayed;
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent += OnInterstitialAdDisplayFailed;
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialAdHidden;
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnInterstitialAdRevenuePaid;
}
private void OnSdkInitialized(MaxSdkBase.SdkConfiguration configuration)
{
AppendLog($"MAX initialized. Success={configuration.IsSuccessfullyInitialized}");
}
private void OnRewardedAdLoaded(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
rewardedLoadFailCount = 0;
AppendLog($"Rewarded loaded callback: {adUnitId}");
bool isReady = MaxSdk.IsRewardedAdReady(adUnitId);
AppendReadyCheck("Rewarded", adUnitId, isReady);
}
private void OnRewardedAdLoadFailed(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
{
rewardedLoadFailCount++;
AppendWarning($"Rewarded load failed: {adUnitId}, attempt={rewardedLoadFailCount}, message={errorInfo.Message}");
}
private void OnRewardedAdDisplayed(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Rewarded displayed: {adUnitId}");
}
private void OnRewardedAdDisplayFailed(string adUnitId, MaxSdkBase.ErrorInfo errorInfo, MaxSdkBase.AdInfo adInfo)
{
AppendWarning($"Rewarded display failed: {adUnitId}, message={errorInfo.Message}");
LoadRewarded();
}
private void OnRewardedAdHidden(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Rewarded hidden: {adUnitId}");
LoadRewarded();
}
private void OnRewardedAdReceivedReward(string adUnitId, MaxSdkBase.Reward reward, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Rewarded received reward: {adUnitId}, label={reward.Label}, amount={reward.Amount}");
}
private void OnRewardedAdRevenuePaid(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Rewarded revenue paid: {adUnitId}, revenue={adInfo.Revenue}");
}
private void OnInterstitialAdLoaded(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
interstitialLoadFailCount = 0;
AppendLog($"Interstitial loaded callback: {adUnitId}");
bool isReady = MaxSdk.IsInterstitialReady(adUnitId);
AppendReadyCheck("Interstitial", adUnitId, isReady);
}
private void OnInterstitialAdLoadFailed(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
{
interstitialLoadFailCount++;
AppendWarning($"Interstitial load failed: {adUnitId}, attempt={interstitialLoadFailCount}, message={errorInfo.Message}");
}
private void OnInterstitialAdDisplayed(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Interstitial displayed: {adUnitId}");
}
private void OnInterstitialAdDisplayFailed(string adUnitId, MaxSdkBase.ErrorInfo errorInfo, MaxSdkBase.AdInfo adInfo)
{
AppendWarning($"Interstitial display failed: {adUnitId}, message={errorInfo.Message}");
LoadInterstitial();
}
private void OnInterstitialAdHidden(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Interstitial hidden: {adUnitId}");
LoadInterstitial();
}
private void OnInterstitialAdRevenuePaid(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
AppendLog($"Interstitial revenue paid: {adUnitId}, revenue={adInfo.Revenue}");
}
private void AppendReadyCheck(string format, string adUnitId, bool isReady)
{
string line = AdReadyStateLog.FormatReadyCheck(format, adUnitId, isReady);
if (isReady)
{
AppendLog(line);
}
else
{
AppendWarning(line);
}
}
private void AppendWarning(string message)
{
AppendLog(message, true);
}
private void AppendLog(string message, bool warning = false)
{
string line = $"[{DateTime.Now:HH:mm:ss}] {message}";
logLines.Add(line);
while (logLines.Count > MaxLogLines)
{
logLines.RemoveAt(0);
}
if (logText != null)
{
logText.text = string.Join("\n", logLines);
}
// This scene is for device-side manual QA, so the UI log is the source of truth.
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70a4079f02f94f47a9a065de6d76f8f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,98 @@
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.EventSystems;
public class AdTestSceneBootstrap : MonoBehaviour
{
private void Awake()
{
EnsureEventSystem();
AdTest adTest = GetComponent<AdTest>();
if (adTest == null)
{
adTest = gameObject.AddComponent<AdTest>();
}
adTest.Configure(
FindButton("InitMax", "Init"),
FindButton("LoadRewardedAd", "LoadRewarded", "Load Rewarded", "RewardedLoad"),
FindButton("RewardedAd", "Max", "ShowRewarded", "Show Rewarded", "RewardedShow"),
FindButton("ForceRewardedAd", "ForceRewarded", "Force Rewarded"),
FindButton("CheckRewardedReady", "CheckRewarded", "Check Rewarded", "RewardedReady"),
FindButton("LoadInterstitialAd", "LoadInterstitial", "Load Interstitial", "InterstitialLoad", "PayList"),
FindButton("ShowInterstitialAd", "ShowInterstitial", "Show Interstitial", "InterstitialShow", "Pay"),
FindButton("ForceInterstitialAd", "ForceInterstitial", "Force Interstitial"),
FindButton("CheckInterstitialReady", "CheckInterstitial", "Check Interstitial", "InterstitialReady"),
FindButton("MediationDebugger", "ATT", "Debugger", "Mediation Debugger"),
FindButton("ClearLog", "Clear Log"),
FindText("Message", "Log", "LogText"));
RenameButton("InitMax", "Init MAX");
RenameButton("LoadRewardedAd", "Load Reward");
RenameButton("CheckRewardedReady", "Check Reward");
RenameButton("RewardedAd", "Rewarded");
RenameButton("ForceRewardedAd", "Force Reward");
RenameButton("LoadInterstitialAd", "Load Inter");
RenameButton("CheckInterstitialReady", "Check Inter");
RenameButton("ShowInterstitialAd", "Show Inter");
RenameButton("ForceInterstitialAd", "Force Inter");
RenameButton("MediationDebugger", "Debugger");
RenameButton("ClearLog", "Clear Log");
}
private void EnsureEventSystem()
{
if (FindObjectOfType<EventSystem>() != null)
{
return;
}
GameObject eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
}
private Button FindButton(params string[] names)
{
foreach (string name in names)
{
GameObject target = GameObject.Find(name);
if (target != null && target.TryGetComponent(out Button button))
{
return button;
}
}
return null;
}
private Text FindText(params string[] names)
{
foreach (string name in names)
{
GameObject target = GameObject.Find(name);
if (target != null && target.TryGetComponent(out Text text))
{
return text;
}
}
return null;
}
private void RenameButton(string buttonName, string label)
{
GameObject target = GameObject.Find(buttonName);
if (target == null)
{
return;
}
Text text = target.GetComponentInChildren<Text>();
if (text != null)
{
text.text = label;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f4c0e3f6b3d4d6b9b8a923dc1274d31
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: