如何实现间隔可变的定时函数调用,解决InvokeRepeating间隔不更新问题
动态间隔调用函数的解决方案
问题原因
Unity的InvokeRepeating方法在被调用时就会固定传入的间隔参数值,后续你修改ratioAlive变量本身不会对已经启动的重复调用产生任何影响。而直接将InvokeRepeating放入Update中执行,会每帧都发起新的重复调用,导致函数被高频触发。
可行实现方案
方案1:监听间隔变量变化,动态重设InvokeRepeating
仅当ratioAlive的数值发生改变时,先取消当前的重复调用,再用新的间隔值重新发起调用,避免每帧执行:
- 首先额外声明一个变量存储上一次的间隔值,用来判断是否需要更新调用:
private float lastRatioAlive;
- 在Start方法中初始化基础调用和存储初始值:
void Start() { lastRatioAlive = ratioAlive; InvokeRepeating("MoveEnemies", 1.0f, ratioAlive); }
- 在Update中仅当间隔值变化时重设调用:
void Update() { // 只有间隔值发生变化时才更新调用规则 if (Mathf.Abs(ratioAlive - lastRatioAlive) > 0.001f) { CancelInvoke("MoveEnemies"); InvokeRepeating("MoveEnemies", 0f, ratioAlive); lastRatioAlive = ratioAlive; } }
方案2:自行在Update中实现计时器逻辑(更灵活)
如果需要更细粒度的控制,不用Unity内置的Invoke体系,自己维护计时器是更稳妥的选择,不需要处理取消调用的逻辑:
- 声明计时器变量:
private float timer = 0f;
- 在Update中自行处理计时逻辑:
void Update() { timer += Time.deltaTime; if (timer >= ratioAlive) { MoveEnemies(); timer = 0f; // 重置计时器 } }
这个方案的间隔会自动跟随ratioAlive的最新值生效,不需要额外的变量监听状态。
注意事项
- 如果使用方案1,要确保
CancelInvoke的方法名和调用的方法名完全一致,避免取消失败 - 如果
ratioAlive可能变为0,需要额外加判断避免逻辑异常
内容的提问来源于stack exchange,提问作者user16671872
相关产品推荐
相关产品推荐

