tween的repeatForever无法和delay或call一起使用

我需求就是我需要先延迟0.4秒然后回调一个动作做相关处理,再让一个节点永远做旋转动画。

  • Creator 版本: 3.5.2

  • 目标平台: Chrome浏览器

  • 重现方式:可以使用官方的测试例子稍加改动就能复现

import { _decorator, Component, Node, tween, Tween } from "cc";
const { ccclass, property, menu } = _decorator;

@ccclass("TweenShowHide")
@menu("tween/TweenShowHide")
export class TweenShowHide extends Component {
  private tweenSH!: Tween<Node>;

  onLoad() {
    this.tweenSH = tween(this.node)
      .delay(0.4)
      .call(() => {
        console.log("回调动作");
      })
      .by(2, { angle: -360 })
      //   .union() 加上这一行有用 但是我不希望把延迟也加上 我希望他是一直旋转
      .repeatForever();
  }

  onEnable() {
    this.tweenSH.start();
  }

  onDisable() {
    this.tweenSH.stop();
  }
}


  • 首个报错: 没有报错

  • 之前哪个版本是正常的: 未测试过

  • 手机型号:

  • 手机浏览器:

  • 编辑器操作系统: MacOS 12.4

  • 重现概率: 100%

他现在只能这么做才有用

import { _decorator, Component, Node, tween, Tween } from "cc";
const { ccclass, property, menu } = _decorator;

@ccclass("TweenShowHide")
@menu("tween/TweenShowHide")
export class TweenShowHide extends Component {
  private tweenSH!: Tween<Node>;
  private tweenSH2!: Tween<Node>;

  onLoad() {
    this.tweenSH = tween(this.node)
      .delay(0.4)
      .call(() => {
        console.log("回调动作");
        this.tweenSH2 = tween(this.node).by(2, { angle: -360 }).repeatForever().start();
      });
  }

  onEnable() {
    this.tweenSH.start();
  }

  onDisable() {
    this.tweenSH.stop();
    this.tweenSH2 && this.tweenSH2.stop();
  }
}
1赞

但是我希望能一直链式调用。。。

试试 then

https://docs.cocos.com/creator/manual/zh/tween/tween-example.html#插入缓动

我也试过 不行的 节点不会旋转 最多到回调动作那里

export class TweenShowHide extends Component {
  private tweenSH!: Tween<Node>;
  private tweenSH2!: Tween<Node>;

  onLoad() {
    this.tweenSH2 = tween(this.node).by(2, { angle: -360 }).repeatForever();
    this.tweenSH = tween(this.node)
      .delay(0.4)
      .call(() => {
        console.log("回调动作");
      })
      .then(this.tweenSH2);
  }

  onEnable() {
    this.tweenSH.start();
  }

  onDisable() {
    this.tweenSH.stop();
    this.tweenSH2 && this.tweenSH2.stop();
  }
}

其实希望 union这个函数能提供一个参数,能指定往前的动作数量,合并前面的部分动作,而不是只能全部。

this.tweenSH2 = tween(this.node).by(2, { angle: -360 }).start();
this.tweenSH = tween(this.node)
  .delay(0.4)
  .call(() => {
    console.log("回调动作");
  })
  .then(this.tweenSH2)
  .repeatForever()
  .start()

这样试试呢?

你这样上来节点就已经在运动了 我希望延迟运动 而且你这样节点也不会一直循环运动 动了两秒就不动了

是的 (凑字数)

试了下,3.5版本的 repeatForever 在链式调用里使用不了(不知道是bug还是其他什么)
不过可以试试repeat
改成这样

tween(this.targetNode)
            .delay(4)
            .call(()=>{
                console.log("tween call 1");
            })
            // .then(tween(this.targetNode).by(2,{angle:-360}).repeatForever())
            // .by(2,{angle:-360}).repeatForever()
            .by(2,{angle:-360}).repeat(Number.MAX_SAFE_INTEGER)
            .call(()=>{
                console.log("tween call 2");
            })
            .start()

Number.MAX_SAFE_INTEGER //这个数字应该可以达到永久了
image

好的 也是一个折中方案

repeatForever 这个使用有限制吗?

平时没怎么用3.x的,所以这个不确定有没有限制,只是看到了这个问题,试了一下,没有深究。
不过猜想一下,repeatForever后面的永远也执行不到,所以repeatForever在链式调用时,后面不能有其他的tween的调用了(没有测试,如果你有时间的话,可以试下,然后把结果发出来一下 :joy:)

我思考了一下
由于是循环动作 但动作执行开始时是按当前属性值开始的 所以循环动作必须是2个动作才可以
比如 A点到B点 的运动 就不能循环
因为, 执行完一次时 对象位置已经在B点了, 没办法再从A点开始移动到B点了

所以要执行这个就必须 在移动到B点后 手动设置对象位置到A点才可以!

delay这个我不知道为何 只要有延迟 就根本不执行 更不循环执行了

这个往前倒腾几个动作数量,会不会数得比较费劲啊?

这应该是 bug,我验证发现,只要有 repeatForever 前面有 >=2 个动作,那么就会出现此问题。我发现已经有个 issue: https://github.com/cocos/cocos-engine/issues/14727
我定位一下。

都过了2年了,你们现在来挖坟,估计对方都因为这个bug失业卖炒饭去了 :rofl:

还在哈哈哈哈 没卖炒饭哈 换种不好看的实现方式罢了

:sweat_smile: :sweat_smile: :sweat_smile: