Unity碰撞器的应用

Wesley13
• 阅读 759

转载自: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;

点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Chase620 Chase620
3年前
Promise从入门到拿Offer之手写Promise
1、Promise构造函数的实现Promise构造函数用来声明示例对象,需要传入一个执行器函数。其中包括resolve函数和reject函数,以及几个重要的属性:状态属性、结果属性和回调函数队列。构造函数的基本框架resolve函数用于异步处理成功后调用的函数。其中包括验证对象状态修改次数,修改promise实例对象状态,异步调用成功的回调函数
菜园前端 菜园前端
1年前
什么是回调函数?
原文链接:什么是回调函数?简单的来说,一个函数作为另外一个函数的参数,可以称为回调函数。这个理解其实不完全对,回调的意义根本没有体现出来,何为回调?也就是说一个函数你定义了,你没有马上的去调用它,而是交给了另外一个函数去调用,这才属于回调函数。缺点直接使用
Wesley13 Wesley13
3年前
Java8函数式编程(A)
将行为作为数据传递函数编程的最直接的表现,莫过于将函数作为数据自由传递,结合泛型推导能力,使代码表达能力获得飞一般的提升。Java8怎么支持函数式编程?主要有三个核心概念:函数接口(Function)流(Stream)聚合器(Collector)函数接口关于函数接口,两件事:函数接口是行为
Stella981 Stella981
3年前
CocosCreator编辑器脚本生命周期函数
CocosCreator为组件脚本提供了生命周期的回调函数。用户只要定义特定的回调函数,Creator就会在特定的时期自动执行相关脚本,用户不需要手工调用它们。目前提供给用户的生命周期回调函数主要有:onLoadstartupdatelateUpdateonDestroyonEnable
Stella981 Stella981
3年前
AVIOInterruptCB结构体分析
1AVIOInterruptCB结构体定义在/usr/include/libavformat/avio.h中有如下的结构体定义,根据头文件中的注释:这是一个回调函数和参数的结构体。有些函数是在阻塞的,用这个回调函数来检查是否中断这个阻塞函数,如果回调函数返回1,那么这个正在阻塞的操作将被中止。那么就用这个结构体里的参数opaque来回调其中的callb
Stella981 Stella981
3年前
JavaScript回调函数的高手指南
摘要:本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。回调函数是每个前端程序员都应该知道的概念之一。回调可用于数组、计时器函数、promise、事件处理中。本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。1.回调函数首先写一个向人打招呼的函数。只需要创建一个接受name参数的函数gree
Stella981 Stella981
3年前
ES6 Promise 对象扯谈
newPromise(/executor/function(resolve,reject){...});Promise的构造函数接收一个函数作为参数,函数里面传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不准确,按照标准来
Wesley13 Wesley13
3年前
Go 语言基础入门教程 —— 函数篇:匿名函数和闭包
匿名函数熟悉Laravel框架(一个PHPWeb框架)的同学对匿名函数应该很熟悉,Laravel框架中有着大量匿名函数的应用场景,比如路由定义、绑定实现到接口等://路由定义再比如Swoole中通过回调函数处理网络事件实现异步事件驱动也是匿名函数的典型应用场景://收到请求时触发可以看到,匿名函数
Stella981 Stella981
3年前
C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
 原创笔记,转载请注明出处!点击【关注】,关注也是一种美德~错误描述:1已启动生成:项目:FirstCode,配置:DebugWin321生成启动时间为2018/2/521:00:30。1InitializeBuildStatus:1 正在