位置系统对程序员来说极度不友好

谢谢你的反馈,你看这样回答满意不

默认如果不设置子节点坐标就是(0,0) (0,0)就是左下角,这有什么好困惑的
这是我们经过多次讨论得出的结论,左下角是一个不常见的设定,现在我们只是想走回常见的道路

锚点是设置一个节点各种动作的点,为什么要影响子节点的位置?
下图修改父节点锚点以后子节点的位置出现了问题

假设大图是一个光标,子节点是光标上的中心点,这个中心点用来发射粒子
左图,美术一开始画了一个十字准心做为大图,子节点(粒子发射点)放在准心正中间。
右图,后来美术把十字准心改成了箭头指针,准心在指针的尖端,子节点(粒子发射点)是不是也应该自动跑到尖端才对?
所以我反而没看到问题在哪,毕竟一般父节点的中心位置的修改,伴随的是图片本身的调整,这时子节点是应该要跟着移动才对。

为什么根节点下的元素是(0,0) 而根节点下元素的子元素的(0,0)却成了中间呢?

根节点(场景)没有尺寸这个概念,所以你在根节点下的对象,默认都会和根节点重合。这也是常见 2D 和 3D 游戏引擎的通用做法。

非常不理解为什么子节点的位置要和父节点的锚点挂钩

请不要单单说不理解,最好提出实际开发中见到的问题,我们来解决实际问题才有意义

相对于中间点左下角确实不常放, 但这对于排版却是很有意义的, 如果节点下有数个子节点, 横竖排列都好. 这些子节点的坐标就会是有些是正数 有些却是负数,中间点常用我们是很容易获得的, 而获取到负数位置对于我们判断是不是很不容易呢?

如果两个图形组成一个图形 , 为什么这个图形围不同锚点运动的时候却要子节点也跟着变化?

假如说我程序创建一个节点, 无论被创建在哪里,位置都应该是我可以想象的, 但现在却要把位置考虑进父节点的锚点, 如果忘记写,会就出错, 比如创建在根节点下就是在左下角, 创建在其他节点下在中间, 或者锚点在其他位置, 那么这个节点的位置就无法想像了 这就是实际问题

如果节点下有数个子节点, 横竖排列都好. 这些子节点的坐标就会是有些是正数 有些却是负数,中间点常用我们是很容易获得的, 而获取到负数位置对于我们判断是不是很不容易呢?

如果父节点的尺寸是 0,你一样会有一堆负数的情况出现。在游戏中,不是所有父节点都有尺寸的。在游戏开发中 local position 出现负数是非常常见的。

如果两个图形组成一个图形 , 为什么这个图形围不同锚点运动的时候却要子节点也跟着变化?

我看不出问题在哪,这种需求很容易满足啊,请拿出具体点的例子

假如说我程序创建一个节点, 无论被创建在哪里,位置都应该是我可以想象的, 但现在却要把位置考虑进父节点的锚点, 如果忘记写,会就出错

原来那样才容易出错吧,子物体的坐标竟然要用父物体的尺寸参与计算…… 而且什么叫现在需要考虑父节点的锚点,还是那句话,请拿出实际例子,因为很多你觉得是问题的,根本不是问题

创建在根节点下就是在左下角, 创建在其他节点下在中间

创建在任何尺寸为 0 的父节点下,子节点都是在父节点正中间。根节点也一样,不存在什么左下角的情况,你会觉得跑到左下角,那是因为根节点本来就在左下角。

原来写一个需要居中的节点 node.setPosition(parent.width/2,parent.height/2)
现在需要写的 node.setPosition(parent.width*(0.5-parent.anchorX),parent.height*(0.5-parent.anchorY))

现在的很容易忘记写现在的这种写法 一旦父节点的锚点不在中心点,位置就不会居中.

比如有一组卡牌,有规律排列, 原来通过获取坐标很容易得出是第几张, 现在这是不容易的, 如果不考虑父节点锚点就会出错. 而锚点除了运动外是常被忽略的, 如果后期不经意变动,那就会出问题.

还有一点就是关于以前游戏的重写

再看下面的这个 , 也是个可能遇到的问题.

居中的节点请让美术直接在子节点上加 Widget,设置对齐到 horizontal center 或 vertical center 就可以了,不需要再写代码了(而且你的代码只能对齐一次,Widget 可以在运行时保持对齐状态)

忘记需要考虑锚点位置是改变规则以后的正常现象,请多一点耐心,转换一下思路,相信很快就能看到新规则带来的各种好处(尤其是编辑器里拼场景时)。

关于你说的通过位置获取索引的问题,我理解你从以前经验中产生的需求是「随手设置一个可以让父节点旋转的点作为锚点,子节点排列不受锚点影响」,但现在整个工作流都重新设计过了,比如卡牌索引的问题,应该是动态创建的时候就保存好索引,这样根本不用去算位置;而需要旋转父节点时,只要知道子节点会围绕父节点的锚点旋转,再根据需要重新设置好锚点位置就可以了吧?

以编辑器为核心搭建 UI 的工作流程和以前用代码写 UI 的流程是完全不同的,所以需要修改一些系统来更好的匹配现在的工作流程。对于旧项目如何移植,我们之后会推出更多案例给大家参考。

原来写一个需要居中的节点 node.setPosition(parent.width/2,parent.height/2)
现在需要写的 node.setPosition(parent.width*(0.5-parent.anchorX),parent.height*(0.5-parent.anchorY))
现在的很容易忘记写现在的这种写法 一旦父节点的锚点不在中心点,位置就不会居中.

居中现在用 nantas 上面说的方法就很好了,不需要程序操心。

如果你就是不想用 widget ,你应该一开始就应该让父节点的 anchor 为 0.5, 0.5,然后子节点保持坐标在 0, 0 就好了。这样最爽了,父节点不论如何动态缩放,子节点都还是能居中。

如果同时你还是希望父节点的 anchor 必须是别的点,那麻烦在父节点上面加一个爷爷节点,由爷爷节点充当父节点的 anchor,父节点保持 anchor 是 0.5, 0.5。

比如有一组卡牌,有规律排列, 原来通过获取坐标很容易得出是第几张, 现在这是不容易的, 如果不考虑父节点锚点就会出错

快过年了,不推荐写这么 hack 的代码…… 很容易被老板查出来,扣你年终奖的。
非要写的话,你把父节点的 anchor 设为 0,0 不就行了吗,毕竟锚点的变动一定是美术方面的需要,或者是策划为了布局方便设置的。如果是卡牌背景图这种常见的 UI 元素,美术是无所谓锚点在哪的,一般都是策划在编辑器里根据布局需要设置好的,不会有人手贱去乱改。

锚点除了运动外是常被忽略的, 如果后期不经意变动,那就会出问题

就算锚点有人需要改,我们也希望的是子物体跟着父物体的锚点动,否则才真的会出问题

关于以前游戏的重写

旧系统如果不愿意改代码,
方法1. 手工在父子节点的中间插入一个节点,节点使用 widget 组件固定在父节点左下角即可。
方法2. 修改父节点的 anchor 为 0,0,然后在父节点上面加一个爷爷节点,由爷爷节点充当父节点的 anchor

这个图看不懂,你的需求能解释下吗?

感谢你的热心反馈,让我们能做得更好。

我再总结一下锚点的作用。
锚点的作用无非两个,标识美术关键元素和方便策划布局。

  • 标识美术关键点:
    这种锚点是由美术在场景里设置的,就像我前面举例的,十字准心和箭头。

此时父节点旋转,子物体必须绕着父物体锚点动 (现在满足,原先满足)。
父节点锚点位置如果变化,子物体应该自动跟着移动 (现在满足,原先不满足)。

  • 方便策划布局:
    如果是卡牌背景图,按钮,图标这些 UI 元素,美术是无所谓锚点在哪的,一般都是策划在编辑器里根据布局需要设置好的。

我们现在鼓励的是策划使用 widget 来做定位,策划其实不再需要通过 anchor 来做布局了。
就算要用 anchor 布局,如果 anchor 需要变,一般是由于 UI 有了新的布局需求,本来就不是改一个 anchor 能解决的事情,更不会有策划手贱去改一个本来设得好好的 anchor。
就算改错了,策划也不可能不预览结果,有错误他自己会及时在编辑器下处理,不需要经过程序解决。

所以你帖子标题说的“位置系统对程序员来说极度不友好”应该是不成立的。

现在的流程确实非常好,组件化了,每个节点自已控制自己,不用再去用庞杂的程序去挨个控制了。 如果因为编辑器不好实现而改变的坐标系统是可以接受的。因为UI是可见的,所以怎么设置坐标都可以吧,只要编辑器里的和表现出来的一样就可以了,好像并不需要改坐标系统。

现在的坐标有这种感觉了 地球自转的时候人能正常的在地球上, 围太阳公转的时候人就要飞到太空去了

那张图意思是 大图和小图组成了一个合成图形,当围绕中心点旋转的时候正常,当不围绕中心点旋转的时候 原来的图形被破坏了

幸好楼上这位没去用unity,不然unity这成了吐槽的对象了

小白评论一下,这种锚点在中间,是很合理的设计的。
对于楼主说的,cocos也提供了api来转换到以左下角为基准的坐标。
可以看看convertToWorldSpaceAR,convertToWorldSpace,convertToNodeSpace,convertToNodeSpaceAR这几个api。理解了之后,用起来就不要太爽了。

幸好楼上这位说了不算。

幸好楼上这位不是开发引擎的老板

真的, 非常不友好, 那种需要大量位置计算的小游戏, 做起来让人发疯, 消除类的定位位置的, cocos 的程序员自己都不做点小游戏试试吗? 你们这么顶就算了, 还把canvas的锚点, 位置锁死了, 这是为什么? 不锁死, 是不是就一堆bug? 说自己加一个空节点的, 自己加了各平行的节点后, 不挂canvas下, 不显示吗? 还是你们有什么好方法, 请不吝赐教.

我刚做了一个消消乐游戏···········
没觉得有什么···········

我从creator 转到 cocos 。十分不习惯了……

我用了五六年的C++和lua,开始不习惯,但后来就习惯了~

photoshop的默认锚点不就是0.5么(旋转的时候是以0.5位置为轴进行旋转的),我看美术们也没有吐槽过。

……Canvas 存在的作用就是帮助定位到屏幕中心,不锁死的话很容易误操作。真的不想要这个定位,就不要放到 Canvas 里面,放外面随便你设置。放外面配合 Widget 来布局简直不要太简单。

本来就不是非得挂在 Canvas 下…… 只是对大多数游戏来说,居中适配屏幕比较常见。你先多看点文档,多看点案例吧,别急着下结论。