Unity碰撞器的应用

Wesley13
• 阅读 455

转载自:http://www.cnblogs.com/88999660/p/3371184.html

转载需注明出处

(初学还不太懂,作为笔记备用)

1.碰撞主要有三个函数,void OnCollisionStay,void OnCollisionEnter和OnCollisionExit,三个函数都是回调函数,都有(collisionInfo : Collision)参数。
 
2.一般而言,子弹等物体要进行与Player的消除碰撞处理:
Physics.IgnoreCollision(clone.collider,this.collider);
 
3.脚本附在子弹上时,collisionInfo对象由Collision类生成,则collisionInfo包含被碰撞对象信息。另外:
①collisionInfo.collider就是子弹撞击的物体的碰撞器,获取被撞击物体的名字则通过变量collisionInfo.collider.name(这不是代表碰撞器类型名,而且组件附加物体的物体名称),经常用这个来判断对不同碰撞对象的处理(子弹与物理世界则消失,子弹与敌人子弹则受力运动,子弹与敌人则消失扣血)。
②collisionInfo.transform可以获得被撞击物体的变换属性。
③collisionInfo.contacts是ContactPoint[]数组。一般只使用collisionInfo.contacts[0],代表碰撞接触点。动态生成爆炸效果时常用,0号元素位置作为出生点位置,用以下结果作为出生旋转值(使爆炸沿碰撞点表面法线方向,更为真实):
 
4.对于某些枪械,比如霰弹枪发射的子弹,有时需要做物体受子弹作用力被击飞的效果(对于敌人除了击飞有时还会伴有摔倒效果),这时首先可以用射线函数判断是否击中物体,并获取子弹击中点:
if (Physics.Raycast (originPosition, direction, hitInfo, distance)){.....}
//这一句是放在player身上的(在每次发射子弹时),个人觉得其实在某些场景物体或者敌人身上附加脚本利用collisionInfo去获取子弹碰撞情况下的撞击点,然后针对性地做各种反应会好一点。不过可能受力方向比较难判断,可以考虑在子弹脚本Start()中保存出生点,再依据碰撞点得到子弹运动方向,注意子弹有无重力都只考虑撞击点y坐标。
获取到击中点后即可对该点施加子弹冲击力:(先判断物体是否属于刚体)
if (hit.rigidbody) hit.rigidbody.AddForceAtPosition(force * direction, hitInfo.point);
 
 
5.爆炸的局部空间动力效果的实现。首先获取在爆炸点的某个球体半径范围内的所有碰撞体:
Collider[] colliders = Physics.OverlapSphere( transform.position,explosionRadius );
此函数除了包含位置,半径外还有默认参数遮罩层级(进行碰撞器筛选)。
接着对所有碰撞体施加力,unity内置了添加爆炸力函数:
foreach (Collider hit in colliders) {   if (!hit)   continue;  //防止碰撞体不存在?貌似多余? 
//防止碰撞体hit不存在rigidbody程序出错,只对存在刚体属性的碰撞体添加爆炸作用力。通过这个区别也可以设置一些不受爆炸影响的物体(比如terrain)。
if (hit.rigidbody) hit.rigidbody.AddExplosionForce(explosionPower, explosionPos,explosionRadius);
//此函数还含有第四个参数upwardsModifier(正数n代表虚拟爆炸点在物体中心的下方n米处),可适当设置以增加一个物体下方的虚拟爆炸力,炸飞效果更酷。参数要适当大,否则虚拟爆炸点在物体内部效果有点奇怪。
附注:AddExplosionForce也可以用于制作球形范围内的引力,只要设置了负的作用力。
 
6.在5中的情况,如果除了有爆炸作用力还需要计算按距离衰减的爆炸杀伤力,首先需要计算每个物体离爆炸点最近的表面点坐标:
 Vector3 closestPoint = hit.rigidbody.ClosestPointOnBounds(explosionPosition);
接着要计算表面点坐标与爆炸中心距离:float distance = Vector3.Distance(closestPoint, explosionPos);
最后依照爆炸威力随距离衰减的原则计算物体所受伤害占爆炸总伤害的百分比:
float damage = (1.0F - Mathf.Clamp01(distance /  explosionRadius))*explosionDamage;

点赞
收藏
评论区
推荐文章
Stella981 Stella981
1年前
Cocos Creator中使用事件中心
exportclassEventCenter{/监听数组/privatelisteners{};/注册事件@paramname事件名称@paramcallback回调函数
Wesley13 Wesley13
1年前
Java8函数式编程(A)
将行为作为数据传递函数编程的最直接的表现,莫过于将函数作为数据自由传递,结合泛型推导能力,使代码表达能力获得飞一般的提升。Java8怎么支持函数式编程?主要有三个核心概念:函数接口(Function)流(Stream)聚合器(Collector)函数接口关于函数接口,两件事:函数接口是行为
Stella981 Stella981
1年前
CocosCreator编辑器脚本生命周期函数
CocosCreator为组件脚本提供了生命周期的回调函数。用户只要定义特定的回调函数,Creator就会在特定的时期自动执行相关脚本,用户不需要手工调用它们。目前提供给用户的生命周期回调函数主要有:onLoadstartupdatelateUpdateonDestroyonEnable
Stella981 Stella981
1年前
AVIOInterruptCB结构体分析
1AVIOInterruptCB结构体定义在/usr/include/libavformat/avio.h中有如下的结构体定义,根据头文件中的注释:这是一个回调函数和参数的结构体。有些函数是在阻塞的,用这个回调函数来检查是否中断这个阻塞函数,如果回调函数返回1,那么这个正在阻塞的操作将被中止。那么就用这个结构体里的参数opaque来回调其中的callb
Wesley13 Wesley13
1年前
java实现多态中的虚函数相关概念
本文转载自参考博客1\.Java虚函数虚函数的存在是为了多态。C中普通成员函数加上virtual关键字就成为虚函数Java中其实没有虚函数的概念,它的普通函数就相当于C的虚函数,动态绑定是Java的默认行为。如果Java中不希望某个函数具有虚函数特性,可以加上final关键字变成非虚函数PS:其实C和Java在虚函
Wesley13 Wesley13
1年前
Go 语言基础入门教程 —— 函数篇:匿名函数和闭包
匿名函数熟悉Laravel框架(一个PHPWeb框架)的同学对匿名函数应该很熟悉,Laravel框架中有着大量匿名函数的应用场景,比如路由定义、绑定实现到接口等://路由定义再比如Swoole中通过回调函数处理网络事件实现异步事件驱动也是匿名函数的典型应用场景://收到请求时触发可以看到,匿名函数
Wesley13 Wesley13
1年前
PHP匿名函数及闭包
匿名函数在编程语言中出现的比较早,最早出现在Lisp语言中,随后很多的编程语言都开始有这个功能了,目前使用比较广泛的Javascript以及C,PHP直到5.3才开始真正支持匿名函数,C的新标准C0x也开始支持了。匿名函数是一类不需要指定标示符,而又可以被调用的函数或子例程,匿名函数可以方便的作为参数传递给其他函数,最常见应用是作为回调函数
Wesley13 Wesley13
1年前
PHP中的NOW()函数
是否有一个PHP函数以与MySQL函数NOW()相同的格式返回日期和时间?我知道如何使用date()做到这一点,但是我问是否有一个仅用于此的函数。例如,返回:2009120100:00:001楼使用此功能:functiongetDatetimeNow(){
Stella981 Stella981
1年前
C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
 原创笔记,转载请注明出处!点击【关注】,关注也是一种美德~错误描述:1已启动生成:项目:FirstCode,配置:DebugWin321生成启动时间为2018/2/521:00:30。1InitializeBuildStatus:1 正在
helloworld_34035044 helloworld_34035044
6个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为