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

Unity协程中如何实现等待另一脚本的布尔变量变为true

问题根因

你当前的代码存在两个核心错误导致逻辑不生效:

  • 循环条件写反:你编写的while(script2.hasTriggered == true)逻辑是只有当变量已经为true时才会进入循环,但初始值为false,协程启动后会直接跳过循环,执行完yield就终止,自然不会等待变量变化
  • yield位置错误:你把yield返回写在了while循环外部,就算条件写对,循环也会在同一帧内卡死执行,不会逐帧判断状态,还会导致主线程阻塞
实现方案

方案1:协程轮询(最低改动)

直接修正协程的等待逻辑,每帧判断变量状态,直到变为true后再执行后续代码:

IEnumerator CallTrigger() {
    // 等待直到hasTriggered变为true
    while(script2.hasTriggered == false){
        // 每帧检查一次,挂起等待下一帧继续判断
        yield return null;
    }
    // 执行到此处说明hasTriggered已为true
    Debug.Log("Success");
    script2.hasTriggered = false;
}

也可以用Unity内置的WaitUntil类简化代码,效果完全一致:

IEnumerator CallTrigger() {
    yield return new WaitUntil(() => script2.hasTriggered);
    Debug.Log("Success");
    script2.hasTriggered = false;
}

方案2:事件回调(性能更优,适配多实例场景)

如果你的场景实例数量较多,不希望每帧轮询消耗性能,可以改用事件通知机制,只有当hasTriggered被赋值为true时才触发后续逻辑,无额外轮询开销:

  1. 首先修改Script2代码,将变量改为属性,值变化时触发回调:
using System; // 注意需要引入System命名空间使用Action
public class Script2 : MonoBehaviour
{
    public event Action OnTriggered;
    private bool _hasTriggered = false;
    public bool hasTriggered
    {
        get => _hasTriggered;
        set
        {
            _hasTriggered = value;
            if(_hasTriggered) OnTriggered?.Invoke();
        }
    }
}
  1. 然后修改Script1的协程逻辑,监听事件即可:
IEnumerator CallTrigger() {
    bool isTriggered = false;
    // 注册事件监听
    script2.OnTriggered += () => isTriggered = true;
    // 等待事件触发
    yield return new WaitUntil(() => isTriggered);
    // 注销事件避免内存泄漏
    script2.OnTriggered -= () => isTriggered = true;
    
    Debug.Log("Success");
    script2.hasTriggered = false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 05:36:09