碰撞函数解析
在众多粒子模块中,Collision模块用于管理场景中粒子对象与其他碰撞体对象的碰撞效果。如下表为Collision模块中包含的属性:
属性名称 | 属性意义 |
---|---|
World/Planes | 指世界或平面模式,若选择的是世界模式,则粒子会与场景中包含碰撞体的游戏对象进行碰撞,如果选择平面模式,则需要指定用于碰撞检测的平面 |
Plane | 若选择平面模式,则在此指定碰撞平面 |
Visualization | 它只在平面模式下有效,用于在场景中的碰撞平面小部件(gizmo)显示为线框(wireframe)还是实体(solid) |
Scale Plane | 它只在平面模式下有效,用于设置上面 Visualization的尺寸 |
Dampen | 阻尼系数,取值范围为(0~1)它描述了粒子对象在一次碰撞后速度损失的程度,其Dampen值越大则粒子速度损失越大。当为0时,粒子速度没损失。当为1时,反之 |
Bounce | 反弹系数。取值(0~2)它描述粒子碰撞后速度反弹的系数,其数值越大则碰撞平面后粒子在平面法线方向的反弹越强 |
Lifetime Loss | 取值范围(0~1),描述粒子第一次碰撞后生命周期的衰减程度,为0时,没有衰减;1时反之。 |
Min Skill Speed | 粒子最小销毁速度。当粒子小于此速度时,粒子就会被销毁。 |
Particle Radius | 指粒子对象半径的大小 |
Collides With | 它只在世界模式下有效,用于碰撞过滤选择 |
Collision Quality | 它只在世界模式下有效,用于碰撞质量 |
Send Collision Message | 用于是否向脚本发送碰撞消息,勾选后,在脚本中能通过函数OnParticleCollision检测到粒子质量;反之,则不能通过此函数检测到粒子碰撞(基本必选) |
当粒子与场景中的碰撞体碰撞时,会触发粒子碰撞事件,这时可以在OnParticleCollision中加入碰撞处理代码
void OnParticleCollision(GameObject other)
若脚本是在与粒子发生碰撞的碰撞体所属的游戏对象上绑定的脚本执行,则other指的是粒子系统对象;
若脚本绑定在粒子系统对象上,则other表示与粒子对象发生碰撞的碰撞体组件所绑定的游戏对象。
OnParticleCollision中一些类和API的意义和用法
1)PariticleSystem代表粒子系统对象
类ParticleSystem继承自Component,表明粒子系统对象是一个组件,可以通过Add Component按钮添加到游戏对象上,也可以在游戏对象上通过GetComponent< ParticleSystem >得到
2)ParticleCollisionEvent描述一次粒子碰撞,包括粒子碰撞时的信息
属性名称 | 属性意义 |
---|---|
collider | 指与粒子发生碰撞的碰撞体对象 |
intersection | 指发生碰撞时的碰撞点在世界坐标系中的坐标值 |
normal | 指发生碰撞时碰撞点的法线方向 |
velocity | 指发生碰撞时粒子的入射速度 |
3)ParticlePhysicsExtensions.GetCollisionEvents用于得到游戏对象上的粒子碰撞事件
public static int GetCollisionEvents(this ParticleSystemps,GameObject go,ParticleCollisionEvent[] collisionEvent);
第一个参数类型为this ParticleSystem,表明该静态方法是ParticleSystem类的扩展方法,可以通过ParticleSystem类的实例进行调用
第二个参数表示了碰撞事件的来源,一般指与粒子发生碰撞的碰撞体
第三个参数是一个输出参数,用以返回从游戏对象上查询到的所有碰撞事件列表,若提供的collisionEvents数组的长度小于碰撞列表的长度,则超过部分会被剪掉,为了保证能得到所有的碰撞事件对象,应调用下面 GetCollisionEvents 函数,以先行得到一个数组尺寸
public static int GetSafeCollisionEventSize ( this ParticleSystem ps );
第四个是上面那个函数,能得到事件需要数组的大小,肯定能容纳。
下面是一个简单的案例
1)先创建一个对象Cube,添加粒子系统,Tag为Cube
2)然后创建脚本
private ParticleCollisionEvent[] collisionEvents=new ParticleCollisionEvent[16];
void OnParticleSystem
{
ParticleSystem ps=other.GetComponent<ParticleSystem>();
int safeLength=ps.getSafeCollisionEventSize();
print("safeLength="+safeLength.ToString());
if(collisionEvents.Length<safeLength)
collisionEvents=new ParticleCollisionEvent[safeLength];
int num=ps.GetCollisionEvents(gameObejct,collisionEvents);
for(int i=0;i<num;++i)
{
ParticleCollisionEvent ev=collisionEvents[i];
Vector3 pos=ev.intersection;
if(ev.collider.tag=="Cube")
print("hit cube at possition:"+pos.Str);
}
}
在上面代码中,先得到粒子系统对象,然后得到碰撞事件列表的长度,再调用粒子系统类的成员函数GetCollosionEvents,得到碰撞事件列表。
此文章参考 unity官方案列精讲