向官方引擎组提一个Creator3D和Creator3.0很想吐槽的设定问题,也包含bug

捕获 就是这个,ray在default层,你不打开和其它层检测当然检测不到了

按你的设置可以了,但是官方文档上的“物理射线章节”居然没解释和备注有射线属于DDEFAULT层,也没有写如何分层射线检测,这文档写得太过敷衍了吧,让用户去猜怎么用。

但是让射线属于哪个层这个设定真的好吗?
假如我的角色是Default层,敌人是Enemy层,我不想让这两个对象做物理碰撞,所以在物理设置面板里设置这两个层不能碰撞,这时我又想通过鼠标用物理射线检测是否点击到敌人,由于这两个层已经设置不能碰撞,而射线又是默认属于Default层,射线检测无效,这样我永远点击不到敌人。

射线是个抽象的东西,就不该属于碰撞层,可以自由选择和哪些层做物理检测。
官方引擎组可以参考一下unity的物理射线怎么用,别人写的射线就是可以自由选择和哪些层进行碰撞,射线本身没有层的概念,方便易用。

写引擎就该怎么方面用户去使用,不应该被概念束缚,因为物理碰撞需要层,所以给射线也强行加上层的概念,最后搞出很多让用户难以理解的东西。

最后还是前面哪个问题,因为碰撞层需要刚体做支持,导致了像“地面”这种静态物体必须要加刚体才能做分层射线检测,真是无力吐槽。

官方出来解释一下,像Unity中的Tag多好,简简单单

对于tag我目前通过节点名字做判断,节点名字后面加下划线和tag名,数量多的时候有100个以上只能含泪一个一个写。检测时先对节点名字做下划线字符串分割,判断第二个字符串的tag值是什么。

关键是场景是美术建立的,命名都是有一定规范的,程序不可能再去修改一遍场景中物体节点名称,Unity中直接多选一类物体批量的设置Tag然后代码中通过这个Tag去检测,这样才对吧,但是Cocos就很难实现这个功能,真的是烦,一会mask,一会Group,一会layer,文档写的也是一塌糊涂。

我也是从unity过来的,很多东西用unity的概念来理解cocos就会陷入坑里,虽然他们结构比较相像。在unity的检测碰撞的mask就是指layer,在cocos里用的时候我把layer的值设置给mask半天没效果,后面才知道有个叫group的东西是专门做物理碰撞分组的,和layer是两个独立的东西。如果用射线,单独设置group还不行,还要设置default层是否和要检测的层能够碰撞,因为射线也是有层的概念的,属于default(既然已经有mask做分层检测了为什么还要给射线默认加个层,没想明白),而这些东西官方文档完全没有写。在unity里简单能实现的一个功能,在cocos里要绕1天找原因。


从creator3d的第一个版本到现在的creator3.0已经一年半了,项目设置里图层解释这个问题怎么没人发现,解释得很清楚Layer层可以做物理射线检测,但是却不行,射线检测的mask只认Physics设置的Group。真是误人啊。

cocos引擎组需要一个好的产品经理,不然做出来的东西,功能实现了,用起来很费劲

@JayceLai

sorry,后面加上物理分组后,这里的文案就不对了。
一开始确实是使用 layer 控制的。后来加了物理碰撞分组后,就拆分出去了。

物理碰撞分组没必要分出去啊,公用layer就可以了,unity就这么做的,别人做了这么多年开发都没问题。你现在分出去了,要管理两个层(layer层和group层),管理难度变大了,我现在用creator3d开发,只能先在layer层命名一次名字,然后再在group层按layer的顺序和名字重复再命名一次,降低管理难度。layer和group还是合在一起好,不然那些从unity或laya转过来的,根本就看不懂你们的设定,很快就放弃了。

1赞

之前也有一樣的問題,後來才發現分組竟然不是用layer分組,而是從剛體分組。
原本用不到剛體的為了分組都必須加上剛體。

简单有简单的好处,复杂有复杂的好处。之前 2.0 还有人吐槽呢。Unity 也有人吐槽渲染和物理必须用同一个分组,看看这个帖子 https://forum.unity.com/threads/separate-physics-and-rendering-layers.505580/ Unity 官方也认可了 layer 分离的方案,并且将会改进。

看了一下核心反馈的问题是物理碰撞组和渲染 layer 的拆分,对渲染 layer 进行分组和对物体的碰撞进行分组的目标完全不同,很可能同样的 layer 需要不同的碰撞组,这种情况下会加大 camera visibility 和 layer 设置的复杂度。假设 layer 和碰撞组是相交的情况,比如

节点 A:场景渲染组,物理是地面,B:场景渲染组,物理是场景中的物体,C:角色渲染组,物理是敌人,D:角色渲染组,物理是主角。

那么不拆分的情况下就需要下面几个 layer

  1. 场景地面
  2. 场景物体
  3. 角色敌人
  4. 角色主角

才能做到比较好得控制渲染和物理,复杂度很高。

加上 layer 掩码给用户的只有 20 位(共 32 位,12 位保留给引擎内部),在大项目中如果物理和渲染分组都比较复杂的情况下,一定会不够用。这是我们拆分的核心原因

我不太明白,用不到刚体就不用物理分组了,加了分组就肯定是用到了物理,那么刚体也是必然会加的。
前面有一个论点是如果集合在节点中设置,就不需要加刚体组件,那是需要引擎底层分析你的组是否需要物理刚体,需要的话主动加上的,该有物理表现的一定会有刚体组件,并没有省掉任何的开销。我们也希望这种开销是显式可注意到的

但是文档方面我们确实做得很不够,还需要加强,把这些改动都说清楚,很抱歉

其实你把问题想复杂了。

一,同一个layer有不同的碰撞组这个问题:

  1. 场景地面 layer: floor
  2. 场景物体 layer: sceneobject
  3. 角色敌人 layer: enemy
  4. 角色主角 layer: player

同一个layer的目的是可以用相同的摄像机渲染,如果这4个物体在不同的层,也可以做到用同一个摄像机渲染,设置摄像机的渲染层掩码就行。剩下的就是相同摄像机下的不同碰撞组,就按layer的碰撞关系处理,完全能解决你说的不拆分碰撞组遇到的问题。你现在拆分碰撞组唯一的用处是,相同碰撞组的物体可以选择用不同摄像机渲染,但是从游戏的角度思考,市面上有哪款游戏有物理交互的多个物体不是用同一个摄像机渲染的,用多个摄像机分别渲染相同碰撞组不同物体的情况几乎就没有,就算有也是运行效率低,画面怪异(因为每个摄像机位置不同)。为了这么一个几乎不存在的用法去拆分碰撞组增加管理难度不值得吧。

二,还有你说的 layer 掩码只有20位,怕不够用。
可能你做引擎时间比较长,没经历过多少实际游戏里的应用。
在游戏开发过程中,并不是什么物体都要做分层的,只有那些要多摄像机渲染和做物理分层碰撞时才会用的上,就算分层,很多相同类型的一类物体都可以用同一个层。我搞u3d也好几年了,无论自己开发的项目还是看别人的项目源码, 一个项目里能用超过10个层就很不错了,就算破天荒会用超过20位掩码,这个完全可以在代码运行过程中动态去修改节点的layer,在不需要掩码处理的时候暂时设位default,用到时手动设置其它图层。

我觉得还是没必要为一个很低概率用到的情况去做渲染层和碰撞层拆分

至于物理分组是否用刚体这个问题,可能就是引擎开发者和游戏开发者思想上的冲突。
在你们眼里可能觉得这样设定没什么,就是多加个刚体而已。但是在开发者眼里自己明明不需要的东西为了实现一些功能,必须把刚体捆绑进来使用,心里就觉得压抑。

在游戏开发中,使用物理就避免不了使用刚体,碰撞器,和碰撞分组,物理射线。,要设用物理就会用到分组,不可能场景了几百个物体都是default碰撞层。但是要做分组就必须涉及刚体,这就导致了很多静态物体,如地面,建筑,石头这些都要加刚体,碰撞器无法做到独立使用,数量多的时候一个一个加刚体就很烦人。我现在用creator3d做项目,用到物理引擎基本能保证要给每个碰撞器强行加刚体,否则无法使用。还有和我相同的从unity转过来使用creator3d开发h5的朋友,看到你们的这种设定也是半天没缓过来,明明unity简单一个碰撞器就能做分组事,到了creator3d,全部要附加刚体。

你们引擎组不接触正式游戏开发的话,是体会不到开发者使用引擎时那种压抑心情

还有个问题,物理碰撞分组目前只能在编辑器设置。无法在代码里动态控制碰撞组间是否可以碰撞,或者两个碰撞器是否可以碰撞。在游戏开发中这些功能是非常常用的。

类似unity这种动态控制碰撞的函数

Physics.IgnoreCollision(collider1,collider2, 是否忽略)。//是否忽略两个碰撞体碰撞
Physics.IgnoreLayerCollision(layer1,layer2,是否忽略)//是否忽略两个图层的碰撞体之间的碰撞

目前c3d物理功能的灵活性比较低

像unity那种layer管理,开发了这么多游戏,大多项目都做得过来。像creator2d,一个group管理渲染和碰撞,对付目前各种游戏都游刃有余。你在creator3d搞这个复杂的layer和group分开管理方式,别人一定用得上很复杂的层管理项目吗,概率比较低吧,真有特别复杂的情况,多创建几个layer,再通过代码动态修改layer也能办得到。

主要是我有用一個3D平面,讓我在滑鼠點擊時,用射線檢測得到平面的x,y座標(如圖)


因為該平面的BoxCollider會跟其他物件產生碰撞,造成物件都無法掉落至平面以下。所以做下列操作:

  1. 在node節點上的Layer分組不用DEFAULT分組,但仍會碰撞,失敗
  2. 添加RigidBody組件,用Group分組,成功
  3. 把RigidBody組件勾勾(active?)取消,仍然不會有碰撞,成功

但移除RigidBody組件就又回到跟1.一樣的情形了。

所以才會有用不到剛體但需要分組的情況。

如果有更好的方式,或是滑鼠點擊取座標的方法,我可以學習一下。

分开layer 和 group是没问题的,但是layer只要通过节点设置就好了,而物理 group 得通过组件设置(每次设置还得展开组件去改属性,操作麻烦
而且有的 静态物体/不需要物理模拟的物体 只需要BoxCollider 碰撞盒,但是碰撞盒却不能通过编辑器设置 group/mask,代码里都是可以设置的,这增加了编辑的成本。