You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:08:41