Unity C#中如何从事件处理器触发外部传入的回调方法?
解决Unity中Interstitial广告加载完成后触发回调的问题
这问题我太熟悉了!核心痛点就是HandleInterstitialLoaded作为独立的事件处理器方法,没办法直接访问RequestInterstitialWithCallback方法里的onAdReady委托参数。下面给你两种实用的解决思路,附完整代码示例:
方法一:使用Lambda表达式闭包捕获回调(最简单直接)
直接在RequestInterstitialWithCallback方法内用Lambda表达式绑定OnAdLoaded事件,这样就能直接捕获到onAdReady委托,同时还能方便地处理事件移除,避免内存泄漏:
private void RequestInterstitialWithCallback(Action<bool> onAdReady ) { interstitial = new InterstitialAd("ca-app-pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // 用Lambda表达式作为事件处理器,直接捕获onAdReady EventHandler<EventArgs> loadedHandler = null; loadedHandler = (sender, args) => { Debug.Log("HandleInterstitialLoaded event received."); // 触发回调,用?.Invoke避免空引用异常 onAdReady?.Invoke(true); // 移除事件监听,防止内存泄漏 interstitial.OnAdLoaded -= loadedHandler; }; interstitial.OnAdLoaded += loadedHandler; interstitial.LoadAd(new AdRequest.Builder().Build()); }
为什么这么做?
- Lambda表达式可以捕获当前方法作用域内的变量(这里就是
onAdReady),事件触发时能直接调用它 - 提前定义
loadedHandler变量是为了能在Lambda内部移除自身的事件绑定,防止广告实例被销毁后还持有引用导致内存泄漏 - 用
onAdReady?.Invoke(true)替代直接调用,是为了避免onAdReady为null时抛出空引用异常
方法二:自定义辅助类存储回调与广告实例(适合复杂场景)
如果你的广告逻辑比较复杂,想保持HandleInterstitialLoaded作为独立方法,可以创建一个辅助类来存储onAdReady和广告实例的关联:
// 辅助类:存储广告实例和对应的回调委托 private class AdCallbackHolder { public InterstitialAd Ad { get; set; } public Action<bool> OnAdReady { get; set; } } private void RequestInterstitialWithCallback(Action<bool> onAdReady ) { interstitial = new InterstitialAd("ca-app-pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // 创建辅助类实例,绑定广告和回调 var callbackHolder = new AdCallbackHolder { Ad = interstitial, OnAdReady = onAdReady }; // 绑定事件处理器,传递辅助类实例 interstitial.OnAdLoaded += (sender, args) => HandleInterstitialLoaded(callbackHolder, args); interstitial.LoadAd(new AdRequest.Builder().Build()); } // 修改事件处理器方法,接收辅助类实例 private void HandleInterstitialLoaded(AdCallbackHolder callbackHolder, EventArgs args) { Debug.Log("HandleInterstitialLoaded event received."); // 触发回调 callbackHolder.OnAdReady?.Invoke(true); // 移除事件监听 callbackHolder.Ad.OnAdLoaded -= (sender, args) => HandleInterstitialLoaded(callbackHolder, args); }
这种方式的优势:
- 适合需要在多个地方复用广告加载逻辑的场景,回调和广告实例的关联更清晰
- 可以在辅助类中添加更多额外状态(比如广告ID、加载次数等),扩展性更强
关键注意事项
- 一定要记得在广告加载完成(或销毁、出错)后移除事件监听,否则会导致内存泄漏
- 建议在广告加载失败时也触发回调(比如
onAdReady?.Invoke(false)),让调用方能根据返回值处理不同情况 - 始终用
?.Invoke()的方式调用回调,避免空引用异常
内容的提问来源于stack exchange,提问作者Asim Roy
相关产品推荐
相关产品推荐

