Unity3d使用MeshCollider检测区域

发表于2016-07-05
评论0 6.7k浏览
     如果想将地图分为几个不同区域,并实时检测人物在哪个小区域,而且区域是不规则形状的类似这种地图。



      很自然的想到使用模型添加meshcollider来通过碰撞检测。做几个小地图形状的meshbox,拼在一块,使用OnTriggerEnter/Stay/Exit来检测。但是首先让我们来看看meshCollider介绍。

Unity3d圣典 网格碰撞器 Mesh Collider
      以下为摘选的mesh collider介绍:
      网格碰撞器利用一个网格资源并在其上构建碰撞器。对于复杂网状模型上的碰撞检测,它要比应用原型碰撞器精确的多。标记为凸起的(Convex )的网格碰撞器才能够和其他网格碰撞器发生碰撞。


A Mesh Collider used on level geometry 用于台阶状物体的网格碰撞器
Properties 属性
1、Material 材质
      引用何种物理材质决定了他和其他对象如何作用。
2、Is Trigger 是否触发器
      如激活,此碰撞器用于触发事件,并且被物理引擎忽略。
3、Mesh 网格
      用于碰撞所引用的网格
4、Smooth Sphere Collisions
      平滑性状碰撞
      当被激活,碰撞网格法线是平滑的。用于平滑表面比如由没有棱角的平滑起伏组成的起伏地标时应该激活。
5、Convex 凸起的
      如激活,该网格碰撞器将会和其他网格碰撞器碰撞。凸起的网格碰撞器限制在255个三角形面内。

Details 细节
      网格碰撞器通过附加在游戏对象上的网格构建碰撞效果,并严格按照所附加对象的Transform属性来设定其位置和大小比例。
      碰撞网格使用背面剔除(或译背面拣选,指正面多边形挡住了在它后面的背面多边形,Direct3D将通过拣选(即删除多余的处理过程)背面多边形来提高效率的过程。)如果一个对象和被背面剔除的网格碰撞,那也不会在物理上碰撞。
      使用网格碰撞器有一些限制条件。通常,两个网格碰撞器之间不会发生碰撞。所有的网格碰撞器可以和任何原型碰撞器碰撞。如果网格标记为凸起的(Convex),那么就可以和其他网格碰撞器碰撞。
      碰撞器作用于刚体使Unity中的物理作用生效。因为刚体允许对象被物理系统控制。碰撞器使对象之间产生碰撞作用。碰撞器必须独立于刚体加在对象上。碰撞器并不一定需要附加刚体,但是要使移动物体具有碰撞效果必须附加刚体。
      当两个碰撞器间产生碰撞并且其中至少一个附加了刚体时,三个碰撞信息会发送给附加他们的对象,这些事件可以被脚本处理,而且允许用户可以选择自己写脚本或使用内置的NVIDIA PhysX引擎创建唯一的行为。
1、Triggers
        一个可供选择的碰撞器使用方法是标记他们为触发器,仅需要选中检视面板中的IsTrigger属性选择框。触发器不受物理引擎控制,当和一个触发器发生碰撞时会发出三个独特的触发信息。触发器用于触发你游戏中的其他事件,比如过场动画、自动门开启、显示教程信息等等,发挥你的想象力吧!
       当然也应该意识到为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体。一个触发器和一个普通碰撞器碰撞,其中之一必须附加刚体。想了解不同类型碰撞的详细情况,可以参考下边进阶部分中的碰撞行为矩阵。
2、Friction and bouncyness 摩擦力和弹力
       摩擦力、弹力和柔软度由物理材质中定义。标准资源( Standard Assets)中包含了大部分常见的物理材质。要使用只需点击物理材质上的下拉箭头然后选中一个,比如冰。你也可以创建你自己的物理材质并调整摩擦力的大小。

Hints 提示
       除非被标记为凸起的(Convex),否则网格碰撞器间不会发生碰撞。因此,它们最常被用于背景对象比如环境布景。
      凸起的网格碰撞器含有的三角形面不能多于255个。
      原型控制器对于对象的物理控制更加节省资源。
      当为游戏对象附加了网格碰撞器,其网格属性将被定义为用于渲染的网格,可以通过指派其他网格来改变。
      要给一个对象添加多个碰撞器,应该创建子对象并给每个子对象添加一个碰撞器。这使每个碰撞器可以被单独操作。
      可以通过场景视图(Scene View )中的线框(gizmos)来查看碰撞器在你的对象上的预期效果。
碰撞器尽量匹配对象的比例。如果有一组不规则伸缩(每一维度上的比例都不相同),只能使用网格碰撞器才能完全匹配。
      如果你想接收通过Transform组件移动的对象的碰撞/触发信息,你必须给移动对象附件刚体。

Advanced 进阶
1、Collider combinations 碰撞器组合
       Unity中有许多不同的碰撞组合。每个游戏都很独特,不同的组合可能更好地适用于不同类型的游戏。如果你在游戏中使用了物理效果,那理解不同的基本碰撞类型会很有帮助,包括它们的常用形式及如何和其他类型的对象作用。
2、Static Collider 静态碰撞器
       指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或者很轻微的移动。对于环境模型十分好用,当和刚体碰撞时而不会移动。
3、Rigidbody Collider 刚体碰撞器
      指的是同时附加了刚体和碰撞器的游戏对象。通过脚本的力量和碰撞完全受物理引擎的影响。可以和只包含碰撞器的游戏对象碰撞。将会成为你游戏中使用物理效果的基本类型碰撞器。
4、Kinematic Rigidbody Collider 运动学刚体碰撞器
      指的是同时包含碰撞器和刚体,并且激活IsKinematic的一类游戏对象,要移动这类游戏对象,要修改它的Transform组件,而不是用力。它们很像静态碰撞器不过对于想要不停地到处移动的碰撞器很好用。这类游戏对象还有许多其他的独特使用情景。
      这类对象可以用于你通常希望用静态碰撞器发出触发事件的情形下。因为触发器必须要有刚体,你应该添加刚体然后启用IsKinematic。这会阻止你的对象因物理作用而移动并且允许接收你希望得到的触发事件。
      运动学刚体启用与否很容易控制。这对创建人偶十分适用,通常,当你希望一个角色依照动画活动,然后由于爆炸或者其他你选择的情况而引起的碰撞导致其变为人偶。这种情况下,很简单,只需要通过脚本将运动学刚体改为普通刚体。
      如果有刚体有时候变得静止不动了,那么它们就是进入休眠了。意味着它们将不受物理变化影响,也就不会移动。如果你把一个运动学刚体从一个休眠的普通刚体下边移走,那休眠的刚体就会被唤醒并重新被物理变化时时影响。所以如果你有许多希望四处移动并有不同的对象要恰好砸到它们的静态碰撞器,那就用运动学刚体碰撞器吧。
5、Collision action matrix 碰撞行为矩阵
       基于两个碰撞对象的配置,可以产生很多不同的效果。下表概括了基于附加不同组件的两个碰撞对象所产生的效果。其中有些组合只能导致碰撞的两个对象中的一个受到影响,.所以考虑到保持标准的规则-物理效果将不会对没有附加刚体的对象生效。
碰撞后有碰撞检测并有碰撞信息发出
Static Collider静态碰撞器Rigidbody Collider刚体碰撞器Kinematic Rigidbody Collider运动学刚体碰撞器Static Trigger Collider静态触发碰撞器Rigidbody Trigger Collider刚体触发碰撞器Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Static Collider 静态碰撞器Y
Rigidbody Collider 刚体碰撞器YYY
Kinematic Rigidbody Collider运动学刚体碰撞器Y
Static Trigger Collider静态触发碰撞器
Rigidbody Trigger Collider刚体触发碰撞器
Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Trigger messages are sent upon collision碰撞后有触发信息
Static Collider静态碰撞器Rigidbody Collider 刚体碰撞器Kinematic Rigidbody Collider 运动学刚体碰撞器Static Trigger Collider静态触发碰撞器Rigidbody Trigger Collider刚体触发碰撞器Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Static Collider 静态碰撞器YY
Rigidbody Collider 刚体碰撞器YYY
Kinematic Rigidbody Collider运动学刚体碰撞器YYY
Static Trigger Collider静态触发碰撞器YYYY
Rigidbody Trigger Collider刚体触发碰撞器YYYYYY
Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器YYYYYY

      PS.以上为我从圣典上copy的去掉英文的介绍,别问我为什么这么做,强迫症没办法,你可以直接去圣典看。

     以下是我做这个功能的情形,使用地图模型块添加meshcollider只用选择converx才能使用IsTrigger=true,但是勾选converx后,我的凹多边形就凹的地方被自动包含为凸多面体,检测将不准确,但是不勾选不能设置为触发器,也不能添加rigidbody。如下:



       所以将人物添加boxcollider,istrigger=true,添加刚体。测试碰撞发现,只有另个物体碰撞时才会触发OnTriggerEnter/Stay/Exit,碰撞结束人物进入地图块后就会调用OnTriggerExit,并不像想象的会一直调用OnTriggerStay,而是有交集碰撞时会一直调用Stay,将meshcollider设为istrigger后发现人物碰撞mesh表面调用enter,进入mesh后一直调用stay,猜测总结为碰撞器只能表面作用,当进入碰撞器内将不再触发碰撞器函数,而触发器是会检测包含区域内的物体的,不仅是在表面碰撞时调用,碰撞器和触发器调用回调函数时间不同。

      由于多个小地图块是拼合在一起的,使用convertx将会检测不准确,不适用convertx无法检测任务在meshbox内的位置。最后突然灵机一动,我为什么要一定使用碰撞检测呢,可以用射线啊。so this。

//利用射线检测区域,触发器检测只能检测凹面体表面位置

 if (Physics.Raycast(new Vector3(gpsX, 1000, gpsY), new Vector3(0, -1, 0), out_hitInfo, 10000, 1 << 11)) 

EnterArea(int.Parse(_hitInfo.collider.name));

}

那就这样吧。

     看了上面的文章 热爱游戏创作的你是不是已经开始热血沸腾了呢?是不是迫不及待的想加入游戏团队成为里面的一员呢?

     福利来啦~赶快加入腾讯GAD交流群,人满封群!每天分享游戏开发内部干货、教学视频、福利活动、和有相同梦想的人在一起,更有腾讯游戏专家手把手教你做游戏!

腾讯GAD游戏程序交流群:484290331 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论