Norman_Lin的博客

个人游戏开发学习博客

cocos creator 添加刚体后父子节点的移动关系

cocos creator 添加刚体后父子节点的移动关系

请大家关注我的微博:@NormanLin_BadPixel坏像素


在开始这篇文章之前,请大家看一下官方说明。

旋转,位移与缩放

旋转,位移与缩放是游戏开发中最常用的功能,几乎每个节点都会对这些属性进行设置。而在物理系统中,系统会自动对节点的这些属性与 box2d 中对应属性进行同步。
有几点信息需要大家注意:

  1. box2d 中只有旋转和位移,并没有缩放,所以如果设置节点的缩放属性时,会重新构建这个刚体依赖的全部碰撞体。一个有效避免这种情况发生的方式是将渲染的节点作为刚体节点的子节点,缩放只对这个渲染节点作缩放,尽量避免对刚体节点进行直接缩放。

  2. 每个物理时间步之后会把所有刚体信息同步到对应节点上去,而处于性能考虑,节点的信息只有在用户对节点相关属性进行显示设置时才会同步到刚体上,并且刚体只会监视他所在的节点,++即如果修改了节点的父节点的旋转位移是不会同步这些信息的++。

父节点的旋转位移是不会同步这些信息的…
旋转位移是不会同步这些信息的…
是不会同步的…


没有错,就是这个设计坑到了我。

问题提要

我们想动态生成几个带刚体的障碍物为一组,这些障碍物在同一个父节点下面,我们想通过移动父节点一起移动这些障碍物。

之前做过几个项目也有这种需求,但是我们用几种技巧避开了物理引擎(能省则省嘛)。这次的项目避不开了,我是先把功能实现了,再给障碍物加上刚体。因为之前一直是用Unity做的游戏,我觉得没有什么问题,但是真正运行后,我懵逼了,所有的障碍物都TM集中在原点。我去查原因,原因如开头所说。

解决方案

咋办呢?只能自己去修改父节点下面的所有刚体的位置了。

方案1

分三层结构。

父节点 -> 子节点 -> 刚体

需要注意的是,刚体的位置旋转信息是跟子节点同步的,真正的位置是由子节点控制。

之后,只要在update里面不断的把刚体的位置旋转信息归0就行了。

方案2

这个方案适合不需要每帧更新位置的。只要在移动的时候更新位置就行。

  1. 在Start方法里面,记录刚体相对父节点的位置旋转信息。
  2. 在移动的时候,把自身的位置旋转信息更新为之前保存的数值就行了。

比如我一个刚体在父节点坐标系下的位置信息是(100,100)。我在第1帧的时候移动了父节点(x,y),然后在移动完后更新刚体的位置为(100,100)。

start(){
    this.offset = child.position;
}

MoveToX(x){
    child.parent.position.x = x;
    child.position.x = this.offset.x;
}

上面的代码继承cc.component,child节点是一个刚体,它的父节点是一个普通的节点。

按理说,这样的移动方式是能更新刚体的位置的,但是,这里还有一个深坑需要大家注意。

假如你的this.offset 的值为0,既刚体相对父节点的位置是(0,0),你会发现,TMD怎么还是不动啊,但是如果不是0,又是可以的。

真的是神奇。怎么办呢?延迟一帧再执行位置更新。代码进行如下修改。

start(){
    this.offset = child.position.sub(child.parent.position);
}

MoveToX(x){
    child.parent.position.x = x;
    this.scheduleOnce(function(){
            child.position.x = this.offset.x;
        },0);
}

没时间去看它底层的代码找出原因,反正这样写之后就可以了。

结束语

用了Laya跟Cocos后,我才知道能用Unity写游戏是多么舒服的事情。

阅读更多
文章标签: Cocos Creator 刚体
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭