Unity的触发器功能很好,但是也有问题。我来讲讲问题以及解决方案。
先上视频给大家看看效果:
自制触发器
首先约定几个特殊名词。
基元游戏物体:Cube、Sphere之类的。
基元碰撞器:BoxCollider、SphereCollider之类的。
基元触发器:把基元碰撞体的IsTrigger选中,就是基元触发器。
高精度网格碰撞器:网格碰撞器不选中Convex,选中Convex会把网格碰撞器凹陷处闭合掉的,这就谈不上高精度。
重叠:也就是触发状态。
用基元触发器来触发一个高精度网格碰撞器:
它只会在基元触发器与高精度网格碰撞器表面有接触时,才会认为是触发状态:
一旦在基元触发器进入到高精度网格碰撞器内部,竟然会判定二者是不触发的,这就很不好:
为了解决这个问题,我苦思冥想,总算想出来一个一定程度上还能行的通的办法,只能说一定程度上行的通,在某些复杂环境下会失效,具体怎么失效,最后再讲。
先讲解决方案的思路,那就是用多道射线来进行内外检测,就是这么朴实无华,我就以图中的Cube和牙齿模型为示例来讲解吧。
把Cube的BoxCollider移除掉,它是无用的东西。牙齿模型的高精度网格碰撞器仍然保留。然后给Cube设置六面点(六个面的中间点)和八顶点(八个角的顶点),这些点用空物体代替就行:
重要的地方来了:
1.首先从遥远处(我这里设置的一百米之外)给立方体的六面点和八顶点分别射出一道射线,总计十四道外围射线。如果十四道外围射线全部在中途被同一游戏物体遮挡住,那就认为立方体在牙齿的内部,设置立方体的触发状态为真。
2.再从立方体的内部检测,六面点和八顶点,那些互相对应的点(对顶点),来回发射射线,也是总计14道射线。为什么要来回发?不能只从A点给B点发,还需要B点给A点发,因为要考虑到万一A点到B点是从网格碰撞器内部到外部,这样会检测不到网格碰撞器的。最终,这14道射线,有任何一道射线被遮挡,那就认为立方体与牙齿表面重叠,设置立方体的触发状态为真。
满足上述两种状况中的任何一种,都认为立方体与牙齿发生了触发状态。
这个博客最重要讲思路,不要局限于是不是只有立方体可以这样做。事实上其他基元游戏物体和网格碰撞器、其他复杂模型和网格碰撞器之间,都可以用这样的思路去做。
或者对于内部检测这块,你可以不用射线,而是继续用Unity本身的触发器,因为内部检测本来就是检测表面重合的,而Unity自带的触发检测是可以做到的。文章来源:https://www.toymoban.com/news/detail-771629.html
代码如下:文章来源地址https://www.toymoban.com/news/detail-771629.html
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/// <summary>
/// 立方体与网格碰撞器的重叠检测
/// </summary>
public class Cube_MeshColliderTrigger : MonoBehaviour
{
Transform selftTransform;
public Transform SelftTransform
{
get
{
if (selftTransform == null)
{
selftTransform = transform;
}
return selftTransform;
}
}
/// <summary>
/// 六面点
/// </summary>
public Transform[] sixPoints;
/// <summary>
/// 八顶点
/// </summary>
public Transform[] eightPoints;
/// <summary>
/// 从远至近-六面点射线检测结果
/// </summary>
到了这里,关于Unity_网格碰撞器-MeshCollider-触发器-Trigger 网格碰撞器(MeshCollider)内部没有触发检测 只在表面有触发检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!