Unity3d使⽤MeshCollider检测区域
如果想将地图分为⼏个不同区域,并实时检测⼈物在哪个⼩区域,⽽且区域是不规则形状的类似这种地图。
很⾃然的想到使⽤模型添加meshcollider来通过碰撞检测。做⼏个⼩地图形状的meshbox,拼在⼀块,使⽤OnTriggerEnter/Stay/Exit 来检测。但是⾸先让我们来看看meshCollider介绍。
以下为摘选的mesh collider介绍:
⽹格碰撞器利⽤⼀个⽹格资源并在其上构建碰撞器。对于复杂⽹状模型上的碰撞检测,它要⽐应⽤原型碰撞器精确的多。标记为凸起的(Convex )的⽹格碰撞器才能够和其他⽹格碰撞器发⽣碰撞。
A Mesh Collider used on level geometry ⽤于台阶状物体的⽹格碰撞器
Properties 属性
Material 材质
引⽤何种物理材质决定了他和其他对象如何作⽤。
Is Trigger 是否触发器
如激活,此碰撞器⽤于触发事件,并且被物理引擎忽略。
Mesh ⽹格
⽤于碰撞所引⽤的⽹格
Smooth Sphere Collisions
平滑性状碰撞
当被激活,碰撞⽹格法线是平滑的。⽤于平滑表⾯⽐如由没有棱⾓的平滑起伏组成的起伏地标时应该激活。
Convex 凸起的
如激活,该⽹格碰撞器将会和其他⽹格碰撞器碰撞。凸起的⽹格碰撞器限制在255个三⾓形⾯内。
Details 细节
⽹格碰撞器通过附加在游戏对象上的⽹格构建碰撞效果,并严格按照所附加对象的Transform属性来设定其位置和⼤⼩⽐例。
碰撞⽹格使⽤背⾯剔除(或译背⾯拣选,指正⾯多边形挡住了在它后⾯的背⾯多边形,Direct3D将通过拣选(即删除多余的处理过程)背⾯多边形来提⾼效率的过程。)如果⼀个对象和被背⾯剔除的⽹格碰撞,那也不会在物理上碰撞。
使⽤⽹格碰撞器有⼀些限制条件。通常,两个⽹格碰撞器之间不会发⽣碰撞。所有的⽹格碰撞器可以和任何原型碰撞器碰撞。如果⽹格标记为凸起的(Convex),那么就可以和其他⽹格碰撞器碰撞。
格标记为凸起的(Convex),那么就可以和其他⽹格碰撞器碰撞。
碰撞器作⽤于刚体使Unity中的物理作⽤⽣效。因为刚体允许对象被物理系统控制。碰撞器使对象之间产⽣碰撞作⽤。碰撞器必须独⽴于刚体加在对象上。碰撞器并不⼀定需要附加刚体,但是要使移动物体具有碰撞效果必须附加刚体。
当两个碰撞器间产⽣碰撞并且其中⾄少⼀个附加了刚体时,三个碰撞信息会发送给附加他们的对象,这些事件可以被脚本处理,⽽且允许⽤户可以选择⾃⼰写脚本或使⽤内置的NVIDIA PhysX引擎创建唯⼀的⾏为。
Triggers
⼀个可供选择的碰撞器使⽤⽅法是标记他们为触发器,仅需要选中检视⾯板中的IsTrigger属性选择框。触发器不受物理引擎控制,当和⼀个触发器发⽣碰撞时会发出三个独特的触发信息。触发器⽤于触发你游戏中的其他事件,⽐如过场动画、⾃动门开启、显⽰教程信息等等,发挥你的想象⼒吧!
当然也应该意识到为了使两个触发器碰撞时发出碰撞事件,其中⼀个必须包含刚体。⼀个触发器和⼀个普通碰撞器碰撞,其中之⼀必须附加刚体。
想了解不同类型碰撞的详细情况,可以参考下边进阶部分中的碰撞⾏为矩阵。
Friction and bouncyness 摩擦⼒和弹⼒
摩擦⼒、弹⼒和柔软度由物理材质中定义。标准资源( Standard Assets)中包含了⼤部分常见的物理材质。要使⽤只需点击物理材质上的下拉箭头然后选中⼀个,⽐如冰。你也可以创建你⾃⼰的物理材质并调整摩擦⼒的⼤⼩。
Hints 提⽰
unity 教程
除⾮被标记为凸起的(Convex),否则⽹格碰撞器间不会发⽣碰撞。因此,它们最常被⽤于背景对象⽐如环境布景。
凸起的⽹格碰撞器含有的三⾓形⾯不能多于255个。
原型控制器对于对象的物理控制更加节省资源。
当为游戏对象附加了⽹格碰撞器,其⽹格属性将被定义为⽤于渲染的⽹格,可以通过指派其他⽹格来改变。
要给⼀个对象添加多个碰撞器,应该创建⼦对象并给每个⼦对象添加⼀个碰撞器。这使每个碰撞器可以被单独操作。
可以通过场景视图(Scene View )中的线框(gizmos)来查看碰撞器在你的对象上的预期效果。
碰撞器尽量匹配对象的⽐例。如果有⼀组不规则伸缩(每⼀维度上的⽐例都不相同),只能使⽤⽹格碰撞器才能完全匹配。
如果你想接收通过Transform组件移动的对象的碰撞/触发信息,你必须给移动对象附件刚体。
Advanced 进阶
Collider combinations 碰撞器组合
Unity中有许多不同的碰撞组合。每个游戏都很独特,不同的组合可能更好地适⽤于不同类型的游戏。如果你在游戏中使⽤了物理效果,那理解不同的基本碰撞类型会很有帮助,包括它们的常⽤形式及如何和其他类型的对象作⽤。
Static Collider 静态碰撞器
指的是没有附加刚体⽽附加了碰撞器的游戏对象。这类对象会保持静⽌或者很轻微的移动。对于环境模型⼗分好⽤,当和刚体碰撞时⽽不会移动。
Rigidbody Collider 刚体碰撞器
指的是同时附加了刚体和碰撞器的游戏对象。通过脚本的⼒量和碰撞完全受物理引擎的影响。可以和只包含碰撞器的游戏对象碰撞。将会成为你游戏中使⽤物理效果的基本类型碰撞器。
Kinematic Rigidbody Collider 运动学刚体碰撞器
指的是同时包含碰撞器和刚体,并且激活IsKinematic的⼀类游戏对象,要移动这类游戏对象,要修改它的Transform组件,⽽不是⽤⼒。它们很像静态碰撞器不过对于想要不停地到处移动的碰撞器很好⽤。这类游戏对象还有许多其他的独特使⽤情景。
这类对象可以⽤于你通常希望⽤静态碰撞器发出触发事件的情形下。因为触发器必须要有刚体,你应该添加刚体然后启⽤IsKinematic。这会阻⽌你的对象因物理作⽤⽽移动并且允许接收你希望得到的触发事件。
运动学刚体启⽤与否很容易控制。这对创建⼈偶⼗分适⽤,通常,当你希望⼀个⾓⾊依照动画活动,然后由于爆炸或者其他你选择的情况⽽引起的碰撞导致其变为⼈偶。这种情况下,很简单,只需要通过脚本将运动学刚体改为普通刚体。
如果有刚体有时候变得静⽌不动了,那么它们就是进⼊休眠了。意味着它们将不受物理变化影响,也就不会移动。如果你把⼀个运动学刚体从⼀个休眠的普通刚体下边移⾛,那休眠的刚体就会被唤醒并重新被物理变化时时影响。所以如果你有许多希望四处移动并有不同的对象要恰好砸到它们的静态碰撞器,那就⽤运动学刚体碰撞器吧。
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 刚
体碰撞器
Y Y Y
Kinematic Rigidbody
Collider运动学刚体碰撞Y
Collider运动学刚体碰撞器
Y Static Trigger Collider静态触发碰撞器Rigidbody Trigger Collider刚体触发碰撞器Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Static Collider 静态碰撞
Rigidbody Collider刚体碰撞器
Kinematic Rigidbody Collider运动学刚
体碰撞器
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 静态碰撞器
Y Y
Rigidbody Collider 刚体碰撞器
Y Y Y
Kinematic Rigidbody Collider运动学刚体碰撞器
Y Y Y
Static Trigger Collider静态触发碰撞器Y Y Y Y
Rigidbody Trigger Collider刚体触发碰撞器Y Y Y Y Y Y
Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Y
Y Y Y Y Y
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
每个⼈物脚本上在updateposition时从头顶1000⾼度向下发射射线,laymark设为meshcollider的layer,检测射线碰撞点在哪个mesh 上,通过meshbox 的name得到是哪个地图,就知道在哪个区域了,代码类下:
//利⽤射线检测区域,触发器检测只能检测凹⾯体表⾯位置
if (Physics.Raycast(new Vector3(gpsX, 1000, gpsY), new Vector3(0, -1, 0), out_hitInfo, 10000, 1 << 11))
{
EnterArea(int.Parse(_llider.name));
}
那就这样吧。