cc.Widget的对齐策略不合理

首次对齐不是在 update 前 start 后,而是在当帧的渲染前。
这样的目的是让用户在代码里对坐标,对 widget 参数的调整能够生效。
如果改成 onLoad/onEnable,那用户对场景的修改,将无法应用到 widget 中。

我也觉得不合理,我用widget做的适配,在onload里根据这个写的代码就不对。

确实有这个问题,我目前的解决办法是,重写一下Widget,重新写的widget继承于cc.widget,在重写的widget组件的onload函数里调用一下updateAlignment函数,然后再移除掉这个widget组件,这样暂时勉强解决了这个问题。。。

updateAlignment?

http://forum.cocos.com/t/widget/43292

任何时候都不应该假设 widget 已经对齐成功。要使用 widget 对齐好的结果,都先调用一次 widget.updateAlignment。这才是正确方式。

这个问题比较悲催的是在onLoad里面去取坐标存起来,如果目标结点是在几层的根结点,要一层一层的去先取widget先updateAlignment.为了简单,我们都是setTimeout(function{},0.1)去取坐标,代码看起来就比较奇怪。
楼主说得这个很有意义,但要cocos改的可能性不大,个人觉得比较合理的处理方式是在onLoad前所有widget生效一次,在渲染前如果调整了参数再生效一次,就是类似脏矩阵的做法。

脏检测确实是最终方案。不过你说的要一层一层去 updateAlignment 好像是没必要的,因为 updateAlignment 本来就会自动调用父节点的 updateAlignment。

原来不只是我一个人会这么做ui,我也是,但是在onload、onenable和start里一层一层手动updateAlignment也没用,因为……这时候渲染根本就还没有开始,而第一次对齐是在渲染前和第一次update和lateUpdate后(在这之前手动调用对齐也没用,因为这个时候画面尺寸还没有初始化,不能获得,也就是说对齐不了),这个地方完全没法控制。以前长期使用unity的ugui,从来没有因为顺序而出现问题,因为人家的对齐时机是在onLoad前的。

特别是在关卡加载的时候的onLoad里,因为没有开始渲染,画面尺寸没有,不管你做什么updateAlignment都没用,除非你延时处理,但是延时处理就会闪啊不是么……如果这个对齐策略是在onLoad前的,那要是你像自己修改了参数再对齐,那手动就可以啊。
只不过啊,基于cocos底层基因的原因,是根本没法放到onLoad前吧,因为新加载关卡的时候onLoad发生在渲染画面大小初始化之前,我觉得官方用before visit事件来处理应该是为了避开这个问题。

用cocos的api去取一个坐标,发现这个坐标很可能不是你想像的那样的,这种感觉真的不好。是否在要文档里加上说明:在取坐标前先要updateAlignment,而且updateAlignment后的坐标也不一定是你想像的那样的。

为什么这样写代码,因为有时候调用了move action,需要回到原位置,就需要一个地方去存这个初始化位置,很尴尬,发现这个坑后写代码都不自然了,总觉得这个坐标会出错,写多了,特别是新手跑过来看你的代码,觉得你的代码怎么写得这么奇怪,好烂,到处setTimeout不是知道是什么鬼,有时setTimeout也会出问题。

文档是有这么写。不过坐标不一定是你想像那样,这个就不是 widget 的问题了。因为在你获取时,渲染还没初始化,所以不管怎样肯定对齐不了。

谢谢反馈,不过如果有这种和逻辑强关联的需求,还是建议自己实现一套 UI 对齐方案,而不是采用现有方案。目前的 Widget 实现比较简单,主要是为了做静态 UI 适配的。如果要加上脏检测,对性能和对引擎的架构都会不太友好。之后我们有足够人手的时候再重新考虑下这个需求吧。

其实吧……自己实现也只能应对动态生成的东西,因为很多时候,我更喜欢在编辑器搭建完全显示的ui,然后游戏运行前初始化隐藏或者挪到其它地方,做好动画前的准备,然后运行的时候播放ui动画(什么淡入淡出啊、滑进啊之类的)。如果ui是动态生成的,那这个无关紧要了,因为关卡加载的以后再动态生成的话,随便在onLoad对齐一下就好了,但是如果关卡是刚加载我就对齐那就麻烦了,因为渲染还没有初始化,无法获得画面大小,但是onLoad和start却已经执行了,so,这个时候就只能延迟对齐了,所以只能闪一下,或者先把东西隐藏起来,然后延时显示并初始化位置,我想,不管是新手还是老手,看到这样“古怪”的逻辑代码都会很不爽的。
解决这个问题的根本就在于让onLoad发生在渲染初始化之后,不过嘛,这种牵涉到底层的关系改动还真不小,我估计官方是不会改的了,cocos的基因确实差了点。:disappointed:

这个方向是错误的,逻辑怎么可能在渲染之后

你的结论是对的,可能 cocos 基因确实不怎样,但是在这个问题上,这两者没有因果关系。widget 这是我单方面的决策,如果是 cocos 的基因,肯定会一开始就把 widget 做成全自动更新的,而不是现在这样。

这个才是关键点好吧。这一块我们会再跟进的。你方便提交一个 demo 吗?就是你说会闪一下的 demo。

使用 widget 一定要把那个默认的 勾勾 去掉,否则没法用。

我也感觉布局很奇怪。要像QT或wxWidgets那样好用就好了。并且我觉得像素和百分比可以同时存在,因为这样可以应对更复杂的布局情况。

现在就是同时存在的,你一定没有试过填入一个%.

我说的闪一下,是指因为刚刚加载完关卡的时候我想要让ui物体不在屏幕内,所以就在onLoad或者start里面设置其位置,但是很显然没有用,所以只能延时设置,这样的话,就会使得这个延时设置会在第一次渲染画面之后执行,so,这里会有一帧的误差。当然只是发生在场景加载的时候。
其实为什么widget的第一次对位并没有放到onLoad前,你我心里都清楚,真要放到onLoad前,要改的东西实在太多了,我也不期待什么,将就着用咯。
我只是一个做游戏的,任何对工具的底层修改,我认为都不应该发生在游戏制作者身上,应该尽可能避开。