Cocos Creator 3.8中Tween在异步Promise函数内失效求助
问题解决:Cocos Creator Tween结合async/await无法正常执行
问题根源
你在magnetTween中直接将this.node.worldPosition作为Tween的目标对象,但worldPosition是只读属性(Readonlycall回调里的resolve永远不会被触发,最终await prm一直处于等待状态。
修复方案
改用一个可修改的临时Vec3变量存储当前世界坐标,将其作为Tween的目标,在onUpdate中把临时变量的同步到节点的世界位置:
修正后的magnetTween方法
private magnetTween(pos: Vec3): Tween<Vec3> { // 克隆当前世界坐标到可修改的Vec3实例 const targetPos = this.node.worldPosition.clone(); const offset = Math.abs(targetPos.x - pos.x); const duration = offset / this.gameConfig.CameraConfig.MagnetSpeed; console.log('tween duration ' + duration) return tween(targetPos).to(duration, pos, { onUpdate: (current: Vec3) => { this.node.setWorldPosition(current); } }); }
magnetTo方法可保留原逻辑
public async magnetTo(obj: Node): Promise<void> { console.log('magnet func start'); const pos = obj.getWorldPosition(); const prm = new Promise<void>((resolve) => { this.magnetTween(pos) .call(() => resolve()) .start(); }); await prm; }
额外优化(可选)
Cocos Creator 3.4+版本的Tween支持直接通过toPromise()方法转换为Promise,无需手动包裹,代码更简洁:
public async magnetTo(obj: Node): Promise<void> { console.log('magnet func start'); const pos = obj.getWorldPosition(); await this.magnetTween(pos).start().toPromise(); }
为什么之前的测试有不同结果?
- 异步函数外的测试可能刚好遇到目标坐标与当前坐标完全一致(
duration=0),Tween会直接触发完成回调; - setTimeout的Promise不受Tween目标限制,自然能正常触发resolve。
内容的提问来源于stack exchange,提问作者Cbubg
相关产品推荐
相关产品推荐

