【分享】Tiled 多边形对象映射成物理 Collider

之前遇到了这个问题,搞定之后和大家做个分享。
因为要做的地图比较大,尝试过几种方式之后发现这个方式是最靠谱的。简单说大概就是把地图做成一层 Tiled ,然后在一个几点上添加多个物理 Collider ,我测试大概在 9600 * 9600 上添加 100+ 的多边形碰撞体,帧率不会下降。

1、使用 Tiled 创建地图,这块就不用多说了。

2、 在 Tiled 中使用多边形工具画出碰撞体。

大概就是这个样子, demo我放到 github 上了。

3、 在 Creator 中地图节点 Map,然后挂上我们做好的地图。同时创建一个新的节点来放置碰撞体,最后结构大概类似这样子:

map 这个节点我们用来放我们 Tiled 地图, collider 节点我们来放我们的碰撞体。其他 Camera ,player 看自己需求了。

4、在 player 节点和 collider 节点上分别挂好 rigibody,还有碰撞分组也需要配置下。

5、创建 collider.js 脚本,挂在 collider 上面,这边 collider 上有点要注意的是, Tiled 的坐标系原点在左上角,Creator 的原点默认中间(Canvas下的节点),所以,我这边偷懒直接改了 collider 节点的锚点和大小,来做到和 Tiled 一样的左上角作为原点。

好了,然后在 collider.js 里把代码撸进去:

onLoad: function () {
        var tiledMap = cc.find("Canvas/map/tiled").getComponent("cc.TiledMap");
        var wallObject = tiledMap.getObjectGroup("collider");
        var objects = wallObject.getObjects();
        for(var i=0; i<objects.length; i++) {
            var dict = objects[i].getProperties();
            var newCollider = cc.find("Canvas/collider").addComponent('cc.PhysicsPolygonCollider')
            // Convert tiled points to ccv2
            var ccv2Points = [];
            for(var j=0; j<dict.points.length; j++) {
                ccv2Points.push( cc.v2(dict.points[j].x, -dict.points[j].y));
            }
            newCollider.points = ccv2Points;
            newCollider.offset = cc.v2(objects[i].offset.x, -objects[i].offset.y);
            newCollider._name = 'formTield';
        }
    },

6、这样子就差不多了,我们在 Tiled 里面编辑的碰撞体已经可以起作用了。

7、要啰嗦的几点:
这边选用多边形适合更多的物体类型,Creator 的支持也是这样子的。其他类似矩形、圆形这样就更简单了。

Demo 在这边,当然我是要 star 的 [滑稽]。

https://github.com/Lucassssss/TiledObj2Collider.git

你给的 points 不合法,到 cc_PhysicsPolygonCollider._createShape 这步调试下

总感觉用多边形检测效率没矩形好:cry:

我们要做的是2.5D的那种。。。。所以一直很疑惑地图该如何做

不规则的形状多边形就好用了

你好,碰撞组将能返回同时碰撞到两个物体的回掉函数吗

cocos creator 3.x 怎么做呢
var dict = objects[i].getProperties(); 语法不支持