关于射线检测

必须吐槽下,这文档真难用

就拿射线检测来说, 至少放一个案例呀, 不然谁知道什么是什么 ?

按照文档走根本走不通, 还要到处去查, 最关键的是本身就很冷门可查的资料也不多

射线的问题我也吐槽过很多,链接帖子就是我以前发的。

官方文档不用看,就30行左右的文字描述能学到什么,最多能知道有射线函数的存在。

和unity的射线系统对比,creator3d的射线写得很low。

物理射线对3d游戏很重要,特别是用于检测鼠标点击3d物体,视野内检测3d物体,还有检测物体距离方向,这些在unity很常用。但是creator3d出了一年半了,官方对射线系统视乎不够重视,提供的API非常少,那简陋的文档就当不存在,案例也没有一个,只能靠自己摸索。

1赞

射线系统还有bug,一旦射线是从一个碰撞器内部发射出去的,马上被这个碰撞器拦截,根本无法检测这个碰撞器以外的碰撞器。

我想说官方API都有,心急可以看引擎源码,只文档上可能延后

看源码 不是每个人都有能力的 如果每个人都能用源码解决 根本也不需要cocos了 文档这东西根本就不存在了

2赞

官方案例中有射线检测的例子。通过关键字ray可以搜到。

你这个问题最起码好几种方法解决。设置检测mask,或者射线发射点放在节点外面。你需要的是找到解决方案。

如果我从玩家的位置发射射线的话,检测前方有没有其它玩家,由于玩家自身有碰撞器,所以会拦截射线。按你说的做法只能是给玩家单独设置一个player碰撞组,通过掩码过滤掉这个玩家组,这样射线就碰撞不到自身玩家了,但是我的射线要检测其它玩家啊,其它玩家也同是player碰撞组,这时导致射线也检测不到其他玩家。这样取巧的方式根本行不通。如果从碰撞器外面发射也有问题,一来需要你运算碰撞器的边缘在哪里,会耗掉你不少时间和精力,很不方便。算有规则的球形和方形碰撞器还行,算圆柱体,圆锥体,胶囊体,还有网格碰撞器的边缘会难倒一大片人。

还有从碰撞器射线内部发射射线还能碰撞到这个碰撞器,这个从使用上根本没意义,我们根本就用不着这样的功能。所以creator2.0的2d射线就会过滤掉内部碰撞器,unity也是会过滤掉。

已经走过的坑,不堪回首,再次回首,两泪纵横,不得不说一句:卧槽,这都没把我劝退!捂脸~

raycast有多个类型。你要是使用检测最近的,那就指挥返回检测到的最近的一个。多看看api和论坛,还有别的api可用,可以返回检测到的所有coliider。

就是为了检测最近的碰撞器啊,用的是PhysicsSystem.instance.raycastClosest,我做的功能是从玩家自身发射射线检测其它玩家,玩家都带有碰撞器,因为被自身碰撞器拦截了,射线出不去了。你说的那些技巧都不可取,这问题还是出在引擎方,不改让内部碰撞器拦截射线。如果你玩过unity或者laya就知道了,别人的射线系统是不会出这种问题的。从碰撞器内部发射射线,这个碰撞器会被忽略掉

1赞

你试试PhysicsSystem.instance.点出别的api?然后再输出看看?你从collider内部发射线检测最近的,必然返回它自己(检测层你又不屏蔽)。我记得论坛有人写过检测前方是否有东西的帖子。

因为别的玩家和自己玩家都属于同一个碰撞层,你检测层屏蔽了就都检测不到了。如果给每个玩家单独分配一个碰撞组掩码,而总的碰撞组掩码只有20个,玩家用了其它物体就没得用了。如果玩家有21个,掩码都不够用。PhysicsSystem有什么api直接进cc.d.ts里一看就知道了,你以为我不会查api吗,提供的射线函数就两个。raycast()和 raycastClosest();一个是返回射线范围内所有的碰撞器,一个是返回最近的碰撞器。你说的都是简单的demo,没有从碰撞器内部发射射线的情况,也没用很多不同物体用到不同碰撞组的情况,做demo都会觉得很简单。如果你做正式项目就知道了,目前的射线系统用着非常难受。很多东西搞不定。

碰撞与检测层是两种东西。对于有内部来说你可以更改节点的碰撞层,为什么不可以你自己有个层,其他敌人一个层?这是一种比较常见的操作。
我自己写过从内部发射射线检测先碰到墙还是先碰到墙后的东西,返回值顺序是不正确的,但是返回的信息是正确的。拿到这些信息你可以做后续处理解决问题了。
说个再直白一点,你从自身范围外发射射线可以吧?方形的话从 ((collider.size.z/2) +0.1)的位置发射射线总检测不到自己了吧。实在有问题你可以上代码针对性的解决。这么说下去问题还存在没有意义。

场景里有超过20个角色一个角色一个层,层不够用啊。

除开自己的部分其他的公用层不可以吗?

不太明白为什么一个角色一个层

你以为就简单一个玩家N个敌人的模式吗。如果是这简单的demo我就不用那么烦心了,玩家一个层,所有敌人一个层,射线发射时过滤掉自己的层就搞定。

但是我有N个玩家和N个敌人。玩家要通过射线检测周围的玩家和敌人,敌人AI也要通过射线检测周围玩家和同伴。
除了玩家和敌人,周围的各种物体还要有自己的层做特殊处理。

不是你那么简单的想法就能搞定的

你还不明白的话,一款类似王者荣耀的5v5 游戏,里面玩家10个,你是要给这十个玩家共同分配一个层(player),还是给每个玩家独立分配一个层(层 player1,player2,… playerN)。如果是共同一个层,就会出现我开始说的,射线把这个层屏蔽了,就检测不到所有玩家了,如果都独立分配一个层,那么变复杂了。而且编辑器最多能提供20个层,还有其他物体要用,你的层不一定够用

3D 物理相关的测试例和Demo
https://github.com/cocos-creator/example-3d/tree/v3.0/physics-3d

内部发出的射线会检测到自身,这个的确是bug,只在 cannon 后端有,解决办法:

  1. 切换成 ammo 后端,或者更新版本
  2. 通过修改源码,引擎里搜索 skipBackFaces ,改成 skipBackfaces

射线在什么层?
射线强制在任意层(最新版本后,射线不会有层,实际上我们一开始就是这么设计的)

为什么要给射线加层?
这是物理引擎的设计,它们都给射线加了层,不管是 Bullet 还是 PhysX,或者是 Cannon

为什么刚体掩码必须包括 DEFAULT 才能被射线检测到?
这不是必须的,因为射线是任意层,只要你的刚体掩码有任意一位,都能被检测到;

为什么刚体掩码为空的时候不能射线检测?
这是由于物理引擎底层的分组掩码算法和碰撞用的是同一套,我们在3.0才发现这个问题,并在最新版本中把所有物理引擎后端的算法都改了,支持掩码为空也能检测,这里感谢 @tangxuanli2014 在另外一贴中的反馈