Unity_网格碰撞器-MeshCollider-触发器-Trigger 网格碰撞器(MeshCollider)内部没有触发检测 只在表面有触发检测

本文探讨了Unity中MeshCollider触发器的问题,当基元触发器进入高精度网格碰撞器内部时,无法正确检测触发状态。提出通过多道射线检测内外部接触的解决方案,并提供了代码示例,但指出该方法在特定复杂情况下可能失效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity的触发器功能很好,但是也有问题。我来讲讲问题以及解决方案。

先上视频给大家看看效果:

自制触发器

首先约定几个特殊名词。

基元游戏物体:Cube、Sphere之类的。

基元碰撞器:BoxCollider、SphereCollider之类的。

基元触发器:把基元碰撞体的IsTrigger选中,就是基元触发器。

高精度网格碰撞器:网格碰撞器不选中Convex,选中Convex会把网格碰撞器凹陷处闭合掉的,这就谈不上高精度。

重叠:也就是触发状态。

用基元触发器来触发一个高精度网格碰撞器:

它只会在基元触发器与高精度网格碰撞器表面有接触时,才会认为是触发状态:

一旦在基元触发器进入到高精度网格碰撞器内部,竟然会判定二者是不触发的,这就很不好:

为了解决这个问题,我苦思冥想,总算想出来一个一定程度上还能行的通的办法,只能说一定程度上行的通,在某些复杂环境下会失效,具体怎么失效,最后再讲。

先讲解决方案的思路,那就是用多道射线来进行内外检测,就是这么朴实无华,我就以图中的Cube和牙齿模型为示例来讲解吧。

把Cube的BoxCollider移除掉,它是无用的东西。牙齿模型的高精度网格碰撞器仍然保留。然后给Cube设置六面点(六个面的中间点)和八顶点(八个角的顶点),这些点用空物体代替就行:

重要的地方来了: 

1.首先从遥远处(我这里设置的一百米之外)给立方体的六面点和八顶点分别射出一道射线,总计十四道外围射线。如果十四道外围射线全部在中途被同一游戏物体遮挡住,那就认为立方体在牙齿的内部,设置立方体的触发状态为真。

2.再从立方体的内部检测,六面点和八顶点,那些互相对应的点(对顶点),来回发射射线,也是总计14道射线。为什么要来回发?不能只从A点给B点发,还需要B点给A点发,因为要考虑到万一A点到B点是从网格碰撞器内部到外部,这样会检测不到网格碰撞器的。最终,这14道射线,有任何一道射线被遮挡,那就认为立方体与牙齿表面重叠,设置立方体的触发状态为真。

满足上述两种状况中的任何一种,都认为立方体与牙齿发生了触发状态。

这个博客最重要讲思路,不要局限于是不是只有立方体可以这样做。事实上其他基元游戏物体和网格碰撞器、其他复杂模型和网格碰撞器之间,都可以用这样的思路去做。

或者对于内部检测这块,你可以不用射线,而是继续用Unity本身的触发器,因为内部检测本来就是检测表面重合的,而Unity自带的触发检测是可以做到的。

代码如下:

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>
    bool[] sixPointsHit_FarToNear = ne
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值