Skip to content

Instantly share code, notes, and snippets.

@jareguo
Last active January 25, 2016 06:39
Show Gist options
  • Save jareguo/dec2d03a883efb5bc23c to your computer and use it in GitHub Desktop.
Save jareguo/dec2d03a883efb5bc23c to your computer and use it in GitHub Desktop.

开始学习的时候为了直观的看效果确实是经常把子节点放在中间,但用来开发的几个项目就不会再以中心点为基点了。

我也算做了10年游戏了,一直都习惯于设置在父节点的中心点。我个人不太理解一个编辑器,创建的子物体默认会跑到父物体的下方这种做法。而且假如我是一个美术/策划,或者将来 Creator 支持 3D 以后,这种子物体一创建就跑到父物体最边上的行为,会更加让人困惑。

假如父节点的大小会动态增加的话。现在的坐标系统就会出问题。

会有什么问题?

假如父节点是超级长的地图话,位置怎么设置

你需要设置的是世界坐标,或者说是屏幕坐标,而不是局部坐标

B是根结点 就是画布 A是跳动的元素 C是地平线 需求1: 把A放在地平线上, 需求2: 判断跳动的包子是否触边 原写法 A.setPosition(B.width/2,C.height) if(A.getPositionX()<0 || A.getPositionX()>B.width) 现写法 A.setPositionY(-B.heightB.anchorX +C.height) if(A.getPositionX()>B.widthB.anchorX || A.getPositionX()>B.width*B.anchorX)

建议如果你不需要设置居中,只需要判断左右,就把父节点的 anchor 设为 0, 0,这样就还是能用原来的写法

如果界面是美工做的。改anchor就又出问题了

请问具体会出什么问题?你是希望子物体永远相对父物体的 anchor 点进行定位吗?可以啊

默认如果不设置子节点坐标就是(0,0) (0,0)就是左下角,这有什么好困惑的

这是我们经过多次讨论得出的结论,左下角是一个不常见的设定,现在我们只是想走回常见的道路

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

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

我的意思是子节点并不想被父节点的anchor影响,你说改父节点的没影响不对吧,现在的坐标系已经不是左下角(0,0)了。 如果父节点大小是超出屏幕的呢

其实每个坐标系都有凑巧能满足的使用场景,这种情况下两种坐标系其实是打平的。否则我也可以说当子节点在父节点中心时 以前:父节点大小超出屏幕,子节点就歪了 现在:父节点大小改变,子节点保持在中心

而且子节点在中间,明显是比在左下角更常见的情况,所以我觉得这个点上还是支持在中间。

放中间难道不知道有tmpNode.setNormalizedPosition(0.5, 0.5);这个函数可以用么

这个方法只是帮你省了代码,解决不了原先坐标系的实际问题。否则我也可以说现在仍然提供了很多种很简单的方法,能满足你左下角定位的需求。

改坐标系之前真有认真讨论过吗?

这是我们经过多次讨论得出的结论,左下角是一个不常见的设定,现在我们只是想走回常见的道路

既然把子节点放中间了,那为什么根节点下的却不是呢?

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

由于子节点和父节点锚点有关联.当后期改变父节点锚点的时候,子节点位置就会出问题.
比如开始从中心点旋转,后期改成右上角旋转. 这时候他上面的子节点位置就会乱掉. 而原来的就不会出现这个问题 再比如写一个跟随鼠标运动的精灵

我亲自测试了一下,并没有看到你说的子节点会乱掉的问题啊,子节点还是好好的绕着父节点的anchor旋转

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

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

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

如果父节点的尺寸是 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 组件就很好了,不需要程序操心。

如果你就是不想用 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。 就算改错了,策划也不可能不预览结果,有错误他自己会及时在编辑器下处理,不需要经过程序解决。

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment