This commit is contained in:
juncong lee 2025-08-30 17:24:58 +08:00
parent c6572464c2
commit 7a083da4fe
17 changed files with 1123 additions and 0 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f29d03f26edcc4074b581c302af83455
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,195 @@
using System;
namespace Script.Common
{
/// <summary>
/// 提供广告SDK功能的统一接口
/// </summary>
public interface IAdService
{
/// <summary>
/// 获取广告客户端名称
/// </summary>
string ClientName { get; }
/// <summary>
/// 初始化广告SDK
/// </summary>
void Initialize();
#region 广
/// <summary>
/// 加载横幅广告
/// </summary>
void LoadBanner();
/// <summary>
/// 检查横幅广告是否可用
/// </summary>
bool IsBannerAvailable();
/// <summary>
/// 显示横幅广告
/// </summary>
void DisplayBanner();
/// <summary>
/// 隐藏横幅广告
/// </summary>
void HideBanner();
/// <summary>
/// 获取横幅广告收益信息
/// </summary>
double GetBannerRevenue();
#endregion
#region 广
/// <summary>
/// 加载插页广告
/// </summary>
void LoadInterstitial();
/// <summary>
/// 检查插页广告是否可用
/// </summary>
bool IsInterstitialAvailable();
/// <summary>
/// 显示插页广告
/// </summary>
void DisplayInterstitial();
/// <summary>
/// 获取插页广告收益信息
/// </summary>
double GetInterstitialRevenue();
#endregion
#region 广
/// <summary>
/// 加载激励广告
/// </summary>
void LoadRewarded();
/// <summary>
/// 检查激励广告是否可用
/// </summary>
bool IsRewardedAvailable();
/// <summary>
/// 显示激励广告
/// </summary>
void DisplayRewarded();
/// <summary>
/// 获取激励广告收益信息
/// </summary>
double GetRewardedRevenue();
#endregion
#region 广
/// <summary>
/// 加载开屏广告
/// </summary>
void LoadSplash();
/// <summary>
/// 检查开屏广告是否可用
/// </summary>
bool IsSplashAvailable();
/// <summary>
/// 显示开屏广告
/// </summary>
void DisplaySplash();
/// <summary>
/// 获取开屏广告收益信息
/// </summary>
double GetSplashRevenue();
#endregion
#region 广
/// <summary>
/// 加载原生广告
/// </summary>
void LoadNative();
/// <summary>
/// 检查原生广告是否可用
/// </summary>
bool IsNativeAvailable();
/// <summary>
/// 显示原生广告
/// </summary>
/// <param name="position">广告位置和尺寸信息</param>
void DisplayNative(NativeAdPosition position);
/// <summary>
/// 移除原生广告
/// </summary>
void RemoveNative();
/// <summary>
/// 获取原生广告收益信息
/// </summary>
double GetNativeRevenue();
#endregion
}
/// <summary>
/// 表示处理回调的信息
/// </summary>
[Serializable]
public struct CallbackResult
{
/// <summary>
/// 回调消息
/// </summary>
public string Message;
/// <summary>
/// 指示广告是否准备就绪
/// </summary>
public bool IsReady;
}
/// <summary>
/// 表示原生广告的位置和尺寸
/// </summary>
[Serializable]
public class NativeAdPosition
{
/// <summary>
/// X坐标
/// </summary>
public int X;
/// <summary>
/// Y坐标
/// </summary>
public int Y;
/// <summary>
/// 广告宽度
/// </summary>
public int Width;
/// <summary>
/// 广告高度
/// </summary>
public int Height;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8c783da4d1e92421e875e007d834b039

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cdbba6a75dfa94e48af5d951115e1816
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,219 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BigoAds.Scripts.Api;
using Script.Common;
using Script.Utils;
using SDK.Utils;
using Unity.VisualScripting;
using UnityEngine;
namespace Script.SDKManager.AdsSDKManager.BigoAdsManager
{
public class BigoAdsManager : NormalSingleton<BigoAdsManager>, IAdService
{
public string ClientName => "BigoAds";
private BigoRewardedAdManager _rewardedAdManager;
private BigoInterstitialAdManager _interstitialAdManager;
private List<string> _interstitialAdUnits;
private List<string> _rewardedAdUnits;
public string bigo_app_id;
public void Initialize()
{
if (string.IsNullOrEmpty(bigo_app_id)) return;
_rewardedAdUnits = GetRewardedAdUnitsFromServer();
_interstitialAdUnits = GetInterstitialAdUnitsFromServer();
BigoAdSdk.OnInitFinish += () =>
{
LoggerUtils.Debug($" bigo sdk init success");
_rewardedAdManager = new BigoRewardedAdManager();
_rewardedAdManager.InitializeAdUnits(
_rewardedAdUnits,
onAdLoaded: OnRewardedAdLoaded,
onAdLoadFailed: OnRewardedAdLoadFailed,
onAdShowed: OnRewardedAdShowed,
onAdDismissed: OnRewardedAdDismissed,
onAdError: OnRewardedAdError,
onAdClicked: OnRewardedAdClicked
);
_interstitialAdManager = new BigoInterstitialAdManager();
_interstitialAdManager.InitializeAdUnits(
_interstitialAdUnits,
onAdLoaded: OnInterstitialAdLoaded,
onAdLoadFailed: OnInterstitialAdLoadFailed,
onAdShowed: OnInterstitialAdShowed,
onAdDismissed: OnInterstitialAdDismissed,
onAdError: OnInterstitialAdError,
onAdClicked: OnInterstitialAdClicked
);
};
// todo
var config = new BigoAdConfig.Builder()
.SetAppId(bigo_app_id)
.SetDebugLog(false)
.Build();
BigoAdSdk.Initialize(config);
}
#region Rewarded
// 各个回调处理方法
private void OnRewardedAdLoaded(string adUnitId)
{
}
private void OnRewardedAdLoadFailed(string adUnitId, int code, string msg)
{
}
private void OnRewardedAdShowed(string adUnitId)
{
}
private void OnRewardedAdDismissed(string adUnitId)
{
_rewardedAdManager.Destroy();
LoadRewarded();
}
private void OnRewardedAdError(string adUnitId, int code, string msg)
{
}
private void OnRewardedAdClicked()
{
}
public void LoadRewarded()
{
foreach (var adUnitId in _rewardedAdUnits)
{
_rewardedAdManager.LoadAd(adUnitId);
}
}
public bool IsRewardedAvailable()
{
return _rewardedAdManager.GetAvailableAdUnits().Count > 0;
}
public void DisplayRewarded()
{
_rewardedAdManager.ShowHighestPayingAd();
}
public double GetRewardedRevenue()
{
return _rewardedAdManager.GetHighestPayingAdRevenue();
}
// 从服务器获取广告位配置
private List<string> GetRewardedAdUnitsFromServer()
{
// todo
return new List<string> { "bigo_reward_unit_1", "bigo_reward_unit_2", "bigo_reward_unit_3" };
}
#region Interstitial
private void OnInterstitialAdLoaded(string adUnitId)
{
}
private void OnInterstitialAdLoadFailed(string adUnitId, int code, string msg)
{
}
private void OnInterstitialAdShowed(string adUnitId)
{
}
private void OnInterstitialAdDismissed(string adUnitId)
{
_interstitialAdManager.Destroy();
LoadInterstitial();
}
private void OnInterstitialAdError(string adUnitId, int code, string msg)
{
}
private void OnInterstitialAdClicked()
{
}
public void LoadInterstitial()
{
foreach (var adUnitId in _interstitialAdUnits)
{
_interstitialAdManager.LoadAd(adUnitId);
}
}
public bool IsInterstitialAvailable()
{
// 检查是否有任意一个广告位可用
return _interstitialAdManager.GetAvailableAdUnits().Count > 0;
}
public void DisplayInterstitial()
{
_interstitialAdManager.ShowHighestPayingAd();
}
public double GetInterstitialRevenue()
{
return _interstitialAdManager.GetHighestPayingAdRevenue();
}
// 从服务器获取广告位配置
private List<string> GetInterstitialAdUnitsFromServer()
{
// 实现从服务器获取广告位ID列表的逻辑
// todo
return new List<string> { "bigo_interstitial_unit_1", "bigo_interstitial_unit_2", "bigo_interstitial_unit_3" };
}
#endregion
#region 广
public void LoadSplash() { }
public bool IsSplashAvailable() { return false; }
public void DisplaySplash() { }
public double GetSplashRevenue() { return 0; }
#endregion
#region 广
public void LoadNative() { }
public bool IsNativeAvailable() { return false; }
public void DisplayNative(NativeAdPosition position) { }
public void RemoveNative() { }
public double GetNativeRevenue() { return 0; }
#endregion
#region 广
public void LoadBanner() { }
public bool IsBannerAvailable() { return false; }
public void DisplayBanner() { }
public void HideBanner() { }
public double GetBannerRevenue() { return 0; }
#endregion
}
#endregion
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 32bd7a6ecbc5e48da929eb774391fe49

View File

@ -0,0 +1,209 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BigoAds.Scripts.Api;
using Script.Utils;
using UnityEngine;
namespace Script.SDKManager.AdsSDKManager.BigoAdsManager
{
public class BigoInterstitialAdManager
{
private Dictionary<string, BigoInterstitialAd> _interstitialAds = new Dictionary<string, BigoInterstitialAd>();
private Dictionary<string, int> _retryCounters = new Dictionary<string, int>();
private Dictionary<string, Action> _loadCallbacks = new Dictionary<string, Action>();
private Dictionary<string, double> _adRevenueCache = new Dictionary<string, double>();
public void InitializeAdUnits(List<string> adUnitIds, Action<string> onAdLoaded = null,
Action<string, int, string> onAdLoadFailed = null,
Action<string> onAdShowed = null,
Action<string> onAdDismissed = null,
Action<string, int, string> onAdError = null,
Action onAdClicked = null)
{
foreach (var adUnitId in adUnitIds)
{
CreateRewardedAd(adUnitId, onAdLoaded, onAdLoadFailed, onAdShowed, onAdDismissed, onAdError, onAdClicked);
}
}
private void CreateRewardedAd(string adUnitId, Action<string> onAdLoaded,
Action<string, int, string> onAdLoadFailed,
Action<string> onAdShowed,
Action<string> onAdDismissed,
Action<string, int, string> onAdError,
Action onAdClicked)
{
if (_interstitialAds.ContainsKey(adUnitId))
{
LoggerUtils.Debug($"Bigo Interstitial Ad unit {adUnitId} already exists");
return;
}
var interstitialAd = new BigoInterstitialAd(adUnitId);
_interstitialAds[adUnitId] = interstitialAd;
_retryCounters[adUnitId] = 0;
_adRevenueCache[adUnitId] = 0;
interstitialAd.OnLoad += () =>
{
_retryCounters[adUnitId] = 0;
_adRevenueCache[adUnitId] = GetAdRevenue(interstitialAd);
LoggerUtils.Debug($"[Bigo] Interstitial -[Load]: {adUnitId} successfully");
onAdLoaded?.Invoke(adUnitId);
};
interstitialAd.OnLoadFailed += ((code, msg) =>
{
_retryCounters[adUnitId]++;
double retryDelay = Math.Pow(2, Math.Min(6, _retryCounters[adUnitId]));
LoggerUtils.Debug($"[Bigo] Interstitial -[Load]: {adUnitId} failed, errorCode ={code}, error message = {msg}");
// 延迟重试加载
_loadCallbacks[adUnitId] = () => LoadAd(adUnitId);
TimerUtils.DelayExecute((float)retryDelay, () => _loadCallbacks[adUnitId]?.Invoke());
onAdLoadFailed?.Invoke(adUnitId, code, msg);
});
interstitialAd.OnAdShowed += (() =>
{
LoggerUtils.Debug($"[Bigo] Interstitial -[interaction]: {adUnitId} show");
onAdShowed?.Invoke(adUnitId);
});
interstitialAd.OnAdDismissed += (() =>
{
LoggerUtils.Debug($"[Bigo] Interstitial -[interaction]: {adUnitId} dismiss");
onAdDismissed?.Invoke(adUnitId);
});
interstitialAd.OnAdError += ((code, msg) =>
{
LoggerUtils.Debug($"[Bigo] Interstitial-[interaction]: {adUnitId} ad error, errorCode ={code}, error message = {msg}");
onAdError?.Invoke(adUnitId, code, msg);
});
interstitialAd.OnAdClicked += () =>
{
onAdClicked?.Invoke();
};
LoadAd(adUnitId);
}
public void LoadAd(string adUnitId)
{
if (_interstitialAds.TryGetValue(adUnitId, out var ad))
{
ad.Load(new BigoInterstitialRequest());
}
}
// 显示价格最高的广告
public void ShowHighestPayingAd()
{
var highestPayingAdUnit = GetHighestPayingAdUnit();
if (!string.IsNullOrEmpty(highestPayingAdUnit))
{
ShowAd(highestPayingAdUnit);
}
}
// 显示特定广告位的广告
private void ShowAd(string adUnitId)
{
if (_interstitialAds.TryGetValue(adUnitId, out var ad))
{
ad.Show();
}
}
// 检查特定广告位是否可用
private bool IsAdAvailable(string adUnitId)
{
return _interstitialAds.TryGetValue(adUnitId, out var ad) && ad.IsLoaded() && !ad.IsExpired();
}
// 获取所有可用的广告位
public List<string> GetAvailableAdUnits()
{
var available = new List<string>();
foreach (var kvp in _interstitialAds)
{
if (kvp.Value.IsLoaded() && !kvp.Value.IsExpired())
{
available.Add(kvp.Key);
}
}
return available;
}
// 获取广告收益
private double GetAdRevenue(BigoInterstitialAd ad)
{
var bid = ad?.GetBid();
if (bid == null) return 0;
return bid.getPrice() / 1000;
}
// 获取特定广告位的收益信息
public double GetAdRevenue(string adUnitId)
{
if (_adRevenueCache.TryGetValue(adUnitId, out var revenue))
{
return revenue;
}
return 0;
}
// 获取价格最高的广告位ID
public string GetHighestPayingAdUnit()
{
string highestPayingAdUnit = null;
double highestRevenue = 0;
foreach (var kvp in _adRevenueCache)
{
var adUnitId = kvp.Key;
var revenue = kvp.Value;
// 确保广告确实已加载并且价格更高
if (IsAdAvailable(adUnitId) && revenue > highestRevenue)
{
highestRevenue = revenue;
highestPayingAdUnit = adUnitId;
}
}
return highestPayingAdUnit;
}
// 获取价格最高的广告收益信息
public double GetHighestPayingAdRevenue()
{
var highestPayingAdUnit = GetHighestPayingAdUnit();
if (!string.IsNullOrEmpty(highestPayingAdUnit) &&
_adRevenueCache.TryGetValue(highestPayingAdUnit, out var revenue))
{
return revenue;
}
return 0;
}
// 清理资源
public void Destroy()
{
foreach (var ad in _interstitialAds.Values)
{
ad.DestroyAd();
}
_interstitialAds.Clear();
_retryCounters.Clear();
_loadCallbacks.Clear();
_adRevenueCache.Clear();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5eeffddf05d3b49bfa0c72cb70f6636c

View File

@ -0,0 +1,209 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BigoAds.Scripts.Api;
using Script.Utils;
using UnityEngine;
namespace Script.SDKManager.AdsSDKManager.BigoAdsManager
{
public class BigoRewardedAdManager
{
private Dictionary<string, BigoRewardedAd> _rewardedAds = new Dictionary<string, BigoRewardedAd>();
private Dictionary<string, int> _retryCounters = new Dictionary<string, int>();
private Dictionary<string, Action> _loadCallbacks = new Dictionary<string, Action>();
private Dictionary<string, double> _adRevenueCache = new Dictionary<string, double>();
public void InitializeAdUnits(List<string> adUnitIds, Action<string> onAdLoaded = null,
Action<string, int, string> onAdLoadFailed = null,
Action<string> onAdShowed = null,
Action<string> onAdDismissed = null,
Action<string, int, string> onAdError = null,
Action onAdClicked = null)
{
foreach (var adUnitId in adUnitIds)
{
CreateRewardedAd(adUnitId, onAdLoaded, onAdLoadFailed, onAdShowed, onAdDismissed, onAdError, onAdClicked);
}
}
private void CreateRewardedAd(string adUnitId, Action<string> onAdLoaded,
Action<string, int, string> onAdLoadFailed,
Action<string> onAdShowed,
Action<string> onAdDismissed,
Action<string, int, string> onAdError,
Action onAdClicked)
{
if (_rewardedAds.ContainsKey(adUnitId))
{
Debug.LogWarning($"Ad unit {adUnitId} already exists");
return;
}
var rewardedAd = new BigoRewardedAd(adUnitId);
_rewardedAds[adUnitId] = rewardedAd;
_retryCounters[adUnitId] = 0;
_adRevenueCache[adUnitId] = 0;
rewardedAd.OnLoad += () =>
{
_retryCounters[adUnitId] = 0;
_adRevenueCache[adUnitId] = GetAdRevenue(rewardedAd);
LoggerUtils.Debug($"[BigoRewarded]-[Load]: {adUnitId} successfully");
onAdLoaded?.Invoke(adUnitId);
};
rewardedAd.OnLoadFailed += ((code, msg) =>
{
_retryCounters[adUnitId]++;
double retryDelay = Math.Pow(2, Math.Min(6, _retryCounters[adUnitId]));
LoggerUtils.Debug($"[BigoRewarded]-[Load]: {adUnitId} failed, errorCode ={code}, error message = {msg}");
// 延迟重试加载
_loadCallbacks[adUnitId] = () => LoadAd(adUnitId);
TimerUtils.DelayExecute((float)retryDelay, () => _loadCallbacks[adUnitId]?.Invoke());
onAdLoadFailed?.Invoke(adUnitId, code, msg);
});
rewardedAd.OnAdShowed += (() =>
{
LoggerUtils.Debug($"[BigoRewarded]-[interaction]: {adUnitId} show");
onAdShowed?.Invoke(adUnitId);
});
rewardedAd.OnAdDismissed += (() =>
{
LoggerUtils.Debug($"[BigoRewarded]-[interaction]: {adUnitId} dismiss");
onAdDismissed?.Invoke(adUnitId);
});
rewardedAd.OnAdError += ((code, msg) =>
{
LoggerUtils.Debug($"[BigoRewarded]-[interaction]: {adUnitId} ad error, errorCode ={code}, error message = {msg}");
onAdError?.Invoke(adUnitId, code, msg);
});
rewardedAd.OnAdClicked += () =>
{
onAdClicked?.Invoke();
};
LoadAd(adUnitId);
}
public void LoadAd(string adUnitId)
{
if (_rewardedAds.TryGetValue(adUnitId, out var ad))
{
ad.Load(new BigoRewardedRequest());
}
}
// 显示价格最高的广告
public void ShowHighestPayingAd()
{
var highestPayingAdUnit = GetHighestPayingAdUnit();
if (!string.IsNullOrEmpty(highestPayingAdUnit))
{
ShowAd(highestPayingAdUnit);
}
}
// 显示特定广告位的广告
private void ShowAd(string adUnitId)
{
if (_rewardedAds.TryGetValue(adUnitId, out var ad))
{
ad.Show();
}
}
// 检查特定广告位是否可用
private bool IsAdAvailable(string adUnitId)
{
return _rewardedAds.TryGetValue(adUnitId, out var ad) && ad.IsLoaded() && !ad.IsExpired();
}
// 获取所有可用的广告位
public List<string> GetAvailableAdUnits()
{
var available = new List<string>();
foreach (var kvp in _rewardedAds)
{
if (kvp.Value.IsLoaded() && !kvp.Value.IsExpired())
{
available.Add(kvp.Key);
}
}
return available;
}
// 获取广告收益
private double GetAdRevenue(BigoRewardedAd ad)
{
var bid = ad?.GetBid();
if (bid == null) return 0;
return bid.getPrice() / 1000;
}
// 获取特定广告位的收益信息
public double GetAdRevenue(string adUnitId)
{
if (_adRevenueCache.TryGetValue(adUnitId, out var revenue))
{
return revenue;
}
return 0;
}
// 获取价格最高的广告位ID
public string GetHighestPayingAdUnit()
{
string highestPayingAdUnit = null;
double highestRevenue = 0;
foreach (var kvp in _adRevenueCache)
{
var adUnitId = kvp.Key;
var revenue = kvp.Value;
// 确保广告确实已加载并且价格更高
if (IsAdAvailable(adUnitId) && revenue > highestRevenue)
{
highestRevenue = revenue;
highestPayingAdUnit = adUnitId;
}
}
return highestPayingAdUnit;
}
// 获取价格最高的广告收益信息
public double GetHighestPayingAdRevenue()
{
var highestPayingAdUnit = GetHighestPayingAdUnit();
if (!string.IsNullOrEmpty(highestPayingAdUnit) &&
_adRevenueCache.TryGetValue(highestPayingAdUnit, out var revenue))
{
return revenue;
}
return 0;
}
// 清理资源
public void Destroy()
{
foreach (var ad in _rewardedAds.Values)
{
ad.DestroyAd();
}
_rewardedAds.Clear();
_retryCounters.Clear();
_loadCallbacks.Clear();
_adRevenueCache.Clear();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c2a850afd5e804d71a3bda35898ee218

8
Assets/Script/Utils.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f3dcbc43a8b6e4fe1a9fc9170c244785
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
namespace Script.Utils
{
public static class LoggerUtils
{
private static bool _enabled = true;
public static bool Enabled
{
get => _enabled;
set => _enabled = value;
}
public static void Debug(object message, Object context = null)
{
if (!_enabled) return;
Log($"[DEBUG] {message}", context);
}
public static void Info(object message, Object context = null)
{
if (!!_enabled) return;
Log($"[INFO] {message}", context);
}
public static void Warning(object message, Object context = null)
{
if (!_enabled) return;
Log($"[WARNING] {message}", context);
}
public static void Error(object message, Object context = null)
{
if (!!_enabled) return;
Log($"[ERROR] {message}", context);
}
private static void Log(string message, Object context = null)
{
if (context != null)
{
UnityEngine.Debug.Log(message, context);
}
else
{
UnityEngine.Debug.Log(message);
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7e6c7794484654e39acf594e7200206a

View File

@ -0,0 +1,165 @@
using UnityEngine;
namespace SDK.Utils
{
public abstract class NormalSingleton<T> where T : new()
{
private static T mInstance;
public static T Instance
{
get
{
if (mInstance == null)
{
mInstance = new T();
}
return mInstance;
}
}
}
/// <summary>
/// 动态(Dynamic)
/// </summary>
public abstract class D_MonoSingleton<T> : MonoBehaviour where T : D_MonoSingleton<T>
{
private static T mInstance = null;
public static T Instance
{
get
{
if (mInstance == null)
{
GameObject tFramewokGo = GameObject.Find("TKFramework");
if (tFramewokGo == null)
{
tFramewokGo = new GameObject("TKFramework");
DontDestroyOnLoad(tFramewokGo);
}
GameObject tGo = new GameObject();
tGo.transform.SetParent(tFramewokGo.transform);
tGo.name = typeof(T).ToString();
tGo.transform.localPosition = Vector3.zero;
tGo.transform.localEulerAngles = Vector3.zero;
tGo.transform.localScale = Vector3.one;
mInstance = tGo.AddComponent<T>();
}
return mInstance;
}
}
protected Transform mTrans;
private void Awake()
{
mTrans = transform;
Initialize();
}
protected virtual void Initialize()
{
}
private void OnDestroy()
{
mInstance = null;
Dispose();
}
protected virtual void Dispose()
{
}
}
/// <summary>
/// 静态(static)
/// </summary>
public abstract class S_MonoSingleton<T> : MonoBehaviour where T : S_MonoSingleton<T>
{
private static T mInstance = null;
public static T Instance
{
get
{
return mInstance;
}
}
private void Awake()
{
if (mInstance != null && mInstance != (T)this)
{
Destroy(gameObject);
return;
}
mInstance = (T)this;
Initialize();
}
protected virtual void Initialize()
{
}
private void OnDestroy()
{
mInstance = null;
Dispose();
}
protected virtual void Dispose()
{
}
}
/// <summary>
/// 静态常驻
/// </summary>
public abstract class O_MonoSingleton<T> : MonoBehaviour where T : O_MonoSingleton<T>
{
private static T mInstance = null;
public static T Instance
{
get
{
return mInstance;
}
}
private void Awake()
{
if (mInstance != null && mInstance != (T)this)
{
Destroy(gameObject);
return;
}
mInstance = (T)this;
DontDestroyOnLoad(gameObject);
Initialize();
}
protected virtual void Initialize()
{
}
private void OnDestroy()
{
mInstance = null;
Dispose();
}
protected virtual void Dispose()
{
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eb54f82607e0946e4ac5cbfb0ca49967

View File

@ -0,0 +1,33 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Script.Utils
{
public static class TimerUtils
{
private static MonoBehaviour _coroutineRunner;
public static void Initialize(MonoBehaviour runner)
{
_coroutineRunner = runner;
}
public static void DelayExecute(float delay, Action action)
{
if (_coroutineRunner != null)
{
_coroutineRunner.StartCoroutine(DelayExecuteCoroutine(delay, action));
}
}
private static IEnumerator DelayExecuteCoroutine(float delay, Action action)
{
yield return new WaitForSeconds(delay);
action?.Invoke();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6e18cf88978e94ad4bd074b3a427bbc9