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

Unity C#委托多实例问题:同类型对象仅最后一个方法生效

解决同一类实例注册委托仅最后一个生效的问题

核心原因分析

你的问题大概率出在委托的调用方式或者返回值处理上:

  • C#中返回非void类型的多播委托,调用时只会返回最后一个执行方法的返回值,但实际上所有注册的方法都会执行。如果你的调用逻辑只处理了这个返回值,就会误以为只有最后一个方法生效。
  • 少数情况是代码中存在用=直接赋值委托的操作,覆盖了之前所有注册的方法。

具体解决方案

1. 修正委托调用逻辑(关键)

如果你的BattleManager是直接调用委托并启动协程,比如:

// 错误的调用方式,只会启动最后一个注册方法的协程
if (onRoundEnd != null)
{
    StartCoroutine(onRoundEnd());
}

这种方式只会拿到最后一个方法的IEnumerator,导致看起来只有最后一个方法生效。正确做法是遍历委托的所有调用列表,逐个启动协程:

// 正确的调用方式,执行所有注册的方法
if (onRoundEnd != null)
{
    foreach (OnRoundEnd handler in onRoundEnd.GetInvocationList())
    {
        StartCoroutine(handler());
    }
}

2. 排查委托被覆盖的情况

全局检查所有操作onRoundEnd的代码,确保所有添加方法的操作都使用+=,没有出现onRoundEnd = xxx;这种直接赋值的语句——这种赋值会直接覆盖之前所有注册的方法,导致只有最后一次赋值的方法生效。

3. 确认Effect的OnRoundEnd是实例方法

确保Effect类中的OnRoundEnd是实例方法(非静态),每个Effect实例的方法都是独立的。示例代码如下:

public class Effect : MonoBehaviour
{
    public BattleManager battleManager;

    public virtual void Init()
    {
        battleManager.onRoundEnd += OnRoundEnd;
    }

    // 实例方法,每个Effect实例的逻辑独立
    public virtual IEnumerator OnRoundEnd()
    {
        // 你的回合结束处理逻辑
        yield return null;
    }
}

4. 验证注册有效性

可以在注册后添加调试代码,确认多个Effect实例都成功注册:

public virtual void Init()
{
    battleManager.onRoundEnd += OnRoundEnd;
    if (battleManager.onRoundEnd != null)
    {
        Debug.Log($"当前注册的OnRoundEnd方法数:{battleManager.onRoundEnd.GetInvocationList().Length}");
    }
}

如果输出的数量和你创建的Effect实例数量一致,说明注册成功,问题出在调用逻辑;如果数量不符,需要排查是否有实例被销毁或注册被覆盖。

内容的提问来源于stack exchange,提问作者Saucyloco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:57:10