using System;
|
using Cysharp.Threading.Tasks;
|
using UnityEngine;
|
|
/// <summary>
|
/// 广告管理器 - 统一封装各平台广告调用
|
/// </summary>
|
public class AdManager : MonoBehaviour
|
{
|
private static AdManager _instance;
|
public static AdManager Instance
|
{
|
get
|
{
|
if (_instance == null)
|
{
|
var go = new GameObject("[AdManager]");
|
_instance = go.AddComponent<AdManager>();
|
DontDestroyOnLoad(go);
|
}
|
return _instance;
|
}
|
}
|
|
[Header("广告配置")]
|
[Tooltip("视频广告冷却时间(秒)")]
|
public float videoAdCooldown = 30f;
|
|
[Tooltip("是否启用广告")]
|
public bool enableAds = true;
|
|
// 广告事件
|
public Action<AdResult> OnVideoAdCompleted;
|
public Action<string> OnAdError;
|
|
// 内部状态
|
private IPlatformService _platform;
|
private float _lastVideoAdTime = 0f;
|
private bool _isShowingAd = false;
|
|
private void Awake()
|
{
|
if (_instance != null && _instance != this)
|
{
|
Destroy(gameObject);
|
return;
|
}
|
_instance = this;
|
DontDestroyOnLoad(gameObject);
|
}
|
|
/// <summary>
|
/// 初始化广告管理器
|
/// </summary>
|
public void Initialize(IPlatformService platform)
|
{
|
_platform = platform;
|
Debug.Log("[AdManager] 广告管理器初始化完成");
|
}
|
|
/// <summary>
|
/// 显示激励视频广告
|
/// </summary>
|
/// <param name="onSuccess">观看完成回调</param>
|
/// <param name="onFail">失败回调</param>
|
public async UniTask<bool> ShowRewardedVideoAd(Action onSuccess = null, Action onFail = null)
|
{
|
if (!enableAds)
|
{
|
Debug.LogWarning("[AdManager] 广告已禁用");
|
onFail?.Invoke();
|
return false;
|
}
|
|
if (_platform == null)
|
{
|
Debug.LogError("[AdManager] 平台服务未初始化");
|
onFail?.Invoke();
|
return false;
|
}
|
|
if (_isShowingAd)
|
{
|
Debug.LogWarning("[AdManager] 已有广告正在播放");
|
onFail?.Invoke();
|
return false;
|
}
|
|
// 检查冷却时间
|
float timeSinceLastAd = Time.time - _lastVideoAdTime;
|
if (timeSinceLastAd < videoAdCooldown)
|
{
|
float remainingTime = videoAdCooldown - timeSinceLastAd;
|
Debug.LogWarning($"[AdManager] 广告冷却中,剩余 {remainingTime:F0} 秒");
|
OnAdError?.Invoke($"广告冷却中,请等待 {remainingTime:F0} 秒");
|
onFail?.Invoke();
|
return false;
|
}
|
|
_isShowingAd = true;
|
|
try
|
{
|
Debug.Log("[AdManager] 开始播放激励视频广告");
|
|
AdResult result = await _platform.ShowAdAsync(AdType.Video);
|
|
if (result.Success && result.Completed)
|
{
|
Debug.Log("[AdManager] 用户观看完广告");
|
_lastVideoAdTime = Time.time;
|
OnVideoAdCompleted?.Invoke(result);
|
onSuccess?.Invoke();
|
return true;
|
}
|
else
|
{
|
Debug.LogWarning($"[AdManager] 广告播放失败: {result.ErrorMessage}");
|
OnAdError?.Invoke(result.ErrorMessage);
|
onFail?.Invoke();
|
return false;
|
}
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"[AdManager] 广告播放异常: {e.Message}");
|
OnAdError?.Invoke(e.Message);
|
onFail?.Invoke();
|
return false;
|
}
|
finally
|
{
|
_isShowingAd = false;
|
}
|
}
|
|
/// <summary>
|
/// 显示横幅广告
|
/// </summary>
|
public async UniTask<bool> ShowBannerAd()
|
{
|
if (!enableAds || _platform == null)
|
return false;
|
|
try
|
{
|
AdResult result = await _platform.ShowAdAsync(AdType.Banner);
|
return result.Success;
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"[AdManager] 横幅广告显示失败: {e.Message}");
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// 显示插屏广告
|
/// </summary>
|
public async UniTask<bool> ShowInterstitialAd()
|
{
|
if (!enableAds || _platform == null)
|
return false;
|
|
try
|
{
|
AdResult result = await _platform.ShowAdAsync(AdType.Interstitial);
|
return result.Success;
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"[AdManager] 插屏广告显示失败: {e.Message}");
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// 检查是否可以播放广告
|
/// </summary>
|
public bool CanShowAd()
|
{
|
if (!enableAds || _platform == null || _isShowingAd)
|
return false;
|
|
float timeSinceLastAd = Time.time - _lastVideoAdTime;
|
return timeSinceLastAd >= videoAdCooldown;
|
}
|
|
/// <summary>
|
/// 获取广告冷却剩余时间
|
/// </summary>
|
public float GetCooldownRemaining()
|
{
|
float timeSinceLastAd = Time.time - _lastVideoAdTime;
|
float remaining = videoAdCooldown - timeSinceLastAd;
|
return Mathf.Max(0f, remaining);
|
}
|
}
|