Unity中订阅Func事件后Coroutine方法未被调用的问题排查
问题分析与解决方案
看起来你的问题出在两个关键地方:协程没有被正确启动,以及多播委托的返回值处理不当。让我一步步帮你解决:
1. 核心问题:协程没有被启动
你的OnFire是返回IEnumerator的Func委托,当你调用OnFire.Invoke(mousePosition)时,只是得到了协程的枚举器对象,但Unity不会自动运行协程——必须通过StartCoroutine()来启动它。而且因为这是多播委托,直接调用Invoke只会返回最后一个订阅者的协程,其他订阅者的逻辑会被忽略。
2. 修正Weapon脚本的Fire方法
把Fire方法改成这样,遍历所有订阅的委托并启动每个协程:
private void Fire() { // 简化鼠标位置的获取,避免重复调用ScreenToWorldPoint Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // 检查事件是否有订阅者 if (OnFire == null) return; // 遍历多播委托的所有订阅者,逐个启动协程 foreach (var fireDelegate in OnFire.GetInvocationList()) { var shootCoroutine = (Func<Vector2, IEnumerator>)fireDelegate; StartCoroutine(shootCoroutine(mousePosition)); } }
3. 额外检查点(避免订阅失败)
除了代码逻辑,还要确认这些配置是否正确:
- Weapon脚本的挂载对象:必须带有
Collider2D(2D场景)或Collider(3D场景),而且物体处于激活状态,这样OnMouseDown才能被触发。 - Bullet脚本的挂载对象:必须在场景中处于激活状态,这样
Start方法才会执行,完成对OnFire事件的订阅。如果是动态生成的Bullet,要确保生成后调用了SetActive(true)。 - MainCamera标签:确保你的相机的
Tag设置为MainCamera,否则Camera.main会返回null,导致mousePosition获取失败,后续逻辑也不会执行。
测试验证
修改后,点击Weapon的Collider区域,你应该能看到控制台输出Shot at (x,y),而且会延迟0.5秒(因为协程里的WaitForSeconds(.5f))。
内容的提问来源于stack exchange,提问作者Sean Carey
相关产品推荐
相关产品推荐

