3.8.1 用Widget组件对齐,改变父级scale后位置不对

NewProject_4.zip (14.2 KB)

  • Creator 版本: 3.8.1

  • 重现方式:在父类上挂一个自定义组件,
    image

NewComponent.ts内容如下:

import { _decorator, Component, Node, tween, v3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('NewComponent')
export class NewComponent extends Component {
   protected onEnable(): void 
   {
       this.node.scale = v3();
       tween(this.node)
       .to(0.15,{scale:v3(1.2,1.2,1)})
       .to(0.1,{scale:v3(1,1,1)})
       .start();
   }
}

子节点上挂widget
image

运行后SpriteSplash的位置不对
image
image

  • 重现概率: 100%

?没有大佬来解惑吗?

我直接用你上传的运行没问题image

出现这情况的原因:

1、Widget的尺寸同步是在onEnable之后的下一帧,同时节点此时的缩放值会同步到UITransform(源码在widget-manager.ts的align函数);

2、你的场景的初始尺寸是1280X720,而不是960X640,这个应该是之前的尺寸,稍微改点东西同步下就会变回960X640了;

3、Tween的执行也是在下一帧,因此Widget执行拿到的缩放值是0,0则不同步,故保持的是场景的尺寸1280X720;

最好的解决方式是通过tween来把节点的缩放值改为0(当然延迟一帧执行代码都可以,不过不简洁):

tween(this.node).set({scale: v3()})…to(0.15, { scale: v3(1.2, 1.2, 1) }).to(0.1, { scale: v3(1, 1, 1) }).start();

感谢,虽然这也许不算bug,但我感觉这样的设计有点不合理。我将父节点的widget的Align Mode改为ALWAYS也解决了

但是动画就有问题了,scale变化会触发Always再重新同步一次尺寸,而导致父节点的尺寸忽大忽小,父节点的尺寸变化又会影响子节点(也是always)。只能说属性冲突了吧,always不适用于缩放动画。

import { _decorator, Component, Node, tween, v3 } from 'cc';

import { FrameOnce, WaitTime } from './WaitingForOperation';

const { ccclass, property } = _decorator;

@ccclass('NewComponet')

export class NewComponet extends Component

{

    protected onLoad(): void

    {

        this.node.scale = v3();

    }

   

    protected async onEnable()

    {

        await FrameOnce();

        await FrameOnce();

        this.node.scale = v3();

        tween(this.node)

        .to(0.15,{scale:v3(1.2,1.2,1)})

        .to(0.1,{scale:v3(1,1,1)})

        .start();

    }

}

这样也可以,其中FrameOnce()是我自定义的一个方法,作用是等待一帧

image 嗯嗯,我也说过了,引擎设计如此,很多组件的刷新调用都是下一帧执行