3.17,4.0中 Action的一个严重bug

Action的执行是以调用step计算dt,然后调用update

ActionInterval的initWithDuration中
_duration = abs(d) <= MATH_EPSILON ? MATH_EPSILON : d;
_elapsed = 0;
设置了_duration和_elapsed,而且duration设置了最小值MATH_EPSILON
而且step中
if (_firstTick)
{
_firstTick = false;
_elapsed = MATH_EPSILON;
}
第一次调用会设置_elapsed,并计算_done

但是ActionInstant中_done的修改是在update中进行的。

这就导致了一个bug,
Sequence::create(TargetedAction::create(CallFunc::create(xxx)),
TargetedAction::create(CallFunc::create(xxx)), nullptr)

对这种Sequence来说,Sequence只会调用子action的update方法,TargetedAction作为一个ActionInterval并不会计算是否执行完成(因为是在step中计算),同时TargetedAction的_duration有时间MATH_EPSILON,这样TargetedAction会被重复调用,TargetedAction中的CallFunc也会被调用多次。

这是我发现的一个必出的严重bug,如果CallFunc中调用一些addChild方法,基本上是必崩溃。ActionInterval和ActionInstant的相互包装,几乎必定出问题。
我觉得设计上是有几个问题的,
1.ActionInterval设置最小时间,3.16之前是0,我不清楚为什么引入这个MATH_EPSILON,但是在sequence中,如果TargetedAction::create(CallFunc::create(xxx))太多,时间必然是偏移比较大的,我建议还是用0。
2._done的计算流程,在ActionInterval和ActionInstant中不一样,一个是step,一个是update,他们单独的时候没问题,混用必然出问题,建议统一在step中进行。
3.step和update的流程不够明确,ActionManager是通过调用step执行Action,但是Sequence,Spawn,TargetedAction等等中又使用update,似乎跳过了step的流程,我觉得还是有问题的,建议规范Action的流程,方便继承和使用,统一从step入口执行会比较好

希望引擎组能早日修复

手动置顶,引擎组都不关注了吗

@huanxinyin @minggo

帮顶@huanxinyin

@huanxinyin @minggo