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

Cocos Creator 3.8中Tween在异步Promise函数内失效求助

问题解决:Cocos Creator Tween结合async/await无法正常执行

问题根源

你在magnetTween中直接将this.node.worldPosition作为Tween的目标对象,但worldPosition是只读属性(Readonly),Tween无法修改它的坐标值,导致补间动画无法正常推进,call回调里的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:31:03