Unity含计时器/键盘中断的while循环冻结问题及修复方案
Unity心理学实验计时/按键响应修复方案(解决冻结+毫秒级精度)
问题根源
你写的while(true)死循环会直接卡住Unity主线程——Unity的渲染、输入检测等核心逻辑都在主线程执行,这个循环会持续占用主线程资源,导致界面完全冻结,连按键检测都无法正常工作。
方案1:使用协程(推荐)
协程能在不阻塞主线程的前提下分帧执行逻辑,同时保证计时精度,完全适配你的需求:
IEnumerator WaitForDurationOrKeyPress() { double startTime = Time.realtimeSinceStartup; while (true) { // 检测是否达到设定时长 if (Time.realtimeSinceStartup - startTime > WordDuration) { break; } // 检测空格键按下 if (Input.GetKeyDown(KeyCode.Space)) { break; } // 让出主线程,等待下一帧执行 yield return null; } // 此处编写计时结束/按键触发后的实验逻辑 Debug.Log("等待阶段结束"); } // 调用协程(例如在Start方法中启动) void Start() { StartCoroutine(WaitForDurationOrKeyPress()); }
精度说明
Time.realtimeSinceStartup记录的是游戏启动到当前的真实时间(不受Time.timeScale影响,比如暂停游戏也会继续计时),精度可达毫秒级,完全满足心理学实验的计时要求。
方案2:在Update中检测(适合多逻辑联动场景)
如果需要和其他帧更新逻辑联动,可以把检测逻辑放到Update方法中:
private double startTime; private bool isWaiting = false; void Start() { // 启动等待流程 startTime = Time.realtimeSinceStartup; isWaiting = true; } void Update() { if (!isWaiting) return; double elapsedTime = Time.realtimeSinceStartup - startTime; // 检测时长或按键触发条件 if (elapsedTime > WordDuration || Input.GetKeyDown(KeyCode.Space)) { isWaiting = false; // 执行后续实验逻辑 Debug.Log("等待阶段结束"); } }
进阶高精度优化(可选)
如果需要更极致的计时精度,可以使用System.Diagnostics.Stopwatch,它的精度比Time.realtimeSinceStartup更高,适合对计时要求极严的实验:
using System.Diagnostics; IEnumerator WaitWithHighPrecision() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (true) { if (stopwatch.Elapsed.TotalSeconds > WordDuration || Input.GetKeyDown(KeyCode.Space)) { stopwatch.Stop(); break; } yield return null; } Debug.Log($"实际等待时长:{stopwatch.Elapsed.TotalMilliseconds:F2}ms"); }
内容的提问来源于stack exchange,提问作者Oren Poliva
相关产品推荐
相关产品推荐

