Unity3d基础入门之物理引擎解析(碰撞器 触发器 等等)

第五章 物理引擎

刚体

简述:

带有刚体组件的游戏物体

Add Component physics Rigidbody

刚体(rigid body)组件可使游戏对象受物理引擎控制,在外力产生真实的物理特性。

想让物体仿真,就加刚体

Ø  属性

质量 Mass :物体的质量。

阻力 Drag :当受力移动时物体受到的空气阻力。0表示没 有空气阻力,极大时可使物体停止运动,通常砖头0.001羽毛设置为10

角阻力 Angular Drag:当受扭力旋转时物体受到的空气阻 力。0表示没有空气阻力,极大时使物体停止旋转。

使用重力 Use Gravity激活,则物体受重力影响

是否是运动学 Is Kinematic :若激活,该物体不再受物理 引擎控制,而只能通过变换组件来操作。

插值 Interpolate:用于缓解刚体运动时抖动

      无 None --不应用插值。

      内插值 Interpolate --基于上一帧的变换来平滑本帧变换。

      外插值 Extrapolate --基于下一帧的预估变换来平滑本帧 变换。

    •碰撞检测 Collision Detection :碰撞检测模式。快速移动的刚体在碰撞时有可能互相穿透,可以设置碰撞检测频率, 但频率越高对物理引擎性能影响越大。    

    不连续 Discrete :不连续碰撞检测。适用于普通碰撞(默 认模式)。

    连续 Continuous :连续碰撞检测

动态连续 Continuous Dynamic  :连续动态碰撞检测,适用 于高速物体。

 

约束Constraints :对刚体运动的约束。

    冻结位置Freeze Position :刚体在世界中沿所选X,Y,Z 轴的移动,将无效。

    冻结旋转 Freeze Rotation :刚体在世界中沿所选的X,Y,Z轴 的旋转,将无效。

碰撞器

Ø  简介

•使刚体具有碰撞效果

•可以单独作用于物体,但是要使移动的物体具有碰撞效果 必须附加刚体组件。

Ø  分类

• 静态碰撞器 Static Collider :只有碰撞器没有刚体的物体

现象保持静止或者轻微移动,如:平面/树木

• 刚体碰撞器 Rigidbody Collider:具有刚体和碰撞器的物体

现象:完全受物理引擎影响

• 运动学刚体碰撞器: 带刚体,且勾选Is Kinematic,此碰撞器

不能添加力,只能通过transform移动。

Ø  属性

• 是否触发器 Is Trigger :如激活,此碰撞器用于触发事件

且被物理引擎忽略

• 材质Material :引用何种物理材质决定了他和其他对象如

何作用。

• 凸起的Convex :不激活则网格碰撞器间没有碰撞效果;

• Mesh 网格:用于碰撞所引用的网格

Ø  物理材质

• 用于调整碰撞对象摩擦力反弹效果

• 属性

动态摩擦力 DynamicFriction移动时摩擦力

静态摩擦力 StaticFriction静止时摩擦力

弹力 (Bounciness):反弹程度

备注:摩擦力、弹力建议0---1之间

摩擦力合并模式 Friction Combine Mode

合并反弹 Bounce Combine

两个碰撞对象摩擦力/弹力的合并方式

平均值Average 最小 Min 最大 Max 相乘Multiply

 

 

 

Ø  碰撞条件!!!

两者具有碰撞组件

运动的物体具有刚体组件

Ø  碰撞三阶段

Collision事件参数类 包含了引发事件时的相关信息,包含了对方的碰撞器

只要碰撞就会执行下面的方法    字母必须一致

1  当进入碰撞时执行    

voidOnCollisionEnter(Collision collOther)//注意不能和下边触发器的Collider弄错

2  当碰撞体与刚体接触时每帧执行

voidOnCollisionStay(Collision collOther)

3  当停止碰撞时执行

voidOnCollisionExit(Collision collOther)

 

other.contacts[0].point   碰撞点的世界坐标

other.contacts[0].normal  碰撞面的法线

Ø  代码引入

//满足碰撞条件的第一帧执行

    private void OnCollisionEnter(Collisionother)

    { //other 事件参数类:包含了引发事件时的相关信息。

        //对方的碰撞器组件

        Debug.Log("Collision:"+other.collider);

        //碰撞点的世界坐标

        //other.contacts[0].point

        //碰撞面的法线

        //other.contacts[0].normal

    }

    //满足触发条件的第一帧执行

    private void OnTriggerEnter(Collider other)

    { //other 事件参数类:包含了引发事件时的相关信息。

        //就是对方的碰撞器组件

        Debug.Log("Trigger:" + other);

    }

触发器

Ø  简介

• 带有碰撞器组件,且Is Trigger属性被勾选的物体 。

• 现象:无碰撞效果。

Ø  触发条件!!!

两者具有碰撞组件

• 其中之一带有刚体组件

• 其中之一勾选 isTrigger

Ø  触发三阶段

当Collider(碰撞体)进入触发器时执行

void OnTriggerEnter(Collider cldOther)

• 当碰撞体与触发器接触时每帧执行

void OnTriggerStay(Collider cldOther)

• 当停止触发时执行

void OnTriggerExit (Collider cldOther)

 

相关应用

案例一:  适合速度慢不知道打谁的物体   用触发器

缺点:用触发检测速度过快的物体不合理

每帧才做一次碰撞(触发)检测,如果物体速度太快,很容易直接越过要碰撞的物体,而检测失败。前一帧不在,后一帧就过了。

解决方案:运动前,就确定好与谁发生碰撞,然后朝向目标点移动。

 

public float moveSpeed = 80;

    privatevoid Movement()

    {

       transform.Translate(0, 0, Time.deltaTime * moveSpeed);

    }

    privatevoid Update()

    {

       Movement();

    }

    privatevoid FixedUpdate()

    {

       Debug.Log(transform.position);

    }

    //当前子弹与其他碰撞器接触时执行

    privatevoid OnTriggerEnter(Collider other)

    {

       Destroy(this.gameObject);

}

案例二:适合高速且躲也躲不掉的物体(子弹)

一、一种对方物体不动,则只需发射一根射线

二、如果对方物体移动,可能打不到,就每帧发射线,射线长度跟速度成正比

像射击类游戏,可以不加子弹,只需做一个弹道就可,省性能。

高速运动的物体,很可能碰撞(触发)检测失败

解决方案:运动前(Start)就确定到与谁发生碰撞,然后朝向目标点移动。

代码:

    public LayerMask layer;

    privateVector3 targetPos;

    privatevoid Start()

    {

       RaycastHit hit;

        //投射射线(起点,方向,结果,距离,参与检测的层)

       if(Physics.Raycast(transform.position, transform.forward, out hit, 500,layer))

        {

            //有目标 

           targetPos = hit.point;//得到检测到的目标点

        }

       else

        {

           //没有目标

           targetPos = transform.TransformPoint(0, 0, 500);//返回前方500m处的点

        }

    }

    privatevoid Update()

    {

       Movement();

        //如果接近目标点,则销毁物体

       if((transform.position - targetPos).sqrMagnitude<0.1f)

        {

           Destroy(this.gameObject);

        }

    }

    privatevoid Movement()

    {

       transform.position = Vector3.MoveTowards(transform.position, targetPos,Time.deltaTime * moveSpeed);//已知目标点的移动,用MoveTowards

    }

关节

关节分类:

铰链关节(最常用)

弹性关节(常用)

固定关节(常用)

角色关节

可配置关节

铰链关节Hinge Joint

铰链关节:将两个刚体(Rigidbody) 组合在一起,从而将其约束为如同通过铰链连接一样进行移动。它十分适合门,也可用于对链条、钟摆等进行模拟效果。

铰链关节组件属性:

属性:                     功能:

•连接体(Connected Body):对关节(Joint) 所依赖的刚体(Rigidbody) 的可选引用。如果未设置,则关节(Joint) 连接到世界坐标。

•锚点(Anchor):主体围绕其摇摆的轴的位置。

•轴(Axis):主体围绕其摇摆的轴的方向。

•使用弹簧(Use Spring):启用使用弹簧属性。

•弹簧(Spring) :对象为移动到位所施加的力。   弹簧力度

•目标位置(Target Position):使刚体(Rigidbody)相对于其连接体达到特定角度。

•阻尼(Damper):此值越高,对象减慢的幅度越大。

•使用电机(Use Motor):启用使用电机(Use Motor) 时使用的电机(Motor) 的属性。

•目标速率(Target Velocity):对象尝试达到的速度。      两个一起用,力度

•力(Force):为达到该速度而应用的力。               达不到速度也达不到

•自由旋转(Free Spin):如果启用,则电机从不用于对旋转制动,仅进行加速。

•使用限制(Use Limits):如果启用,则铰链角度会限制在最小(Min) 和最大(Max)值内。

•限制(Limits):启用使用限制(Use Limits)s 时使用的限制(Limits) 的属性。

•最小(Min):旋转可以达到的最小角度。

•最大(Max):旋转可以达到的最大角度。

•最小反弹(Min Bounce):对象在命中最小停止时反弹的量。

•最大反弹(Max Bounce):对象在命中最大停止时反弹的量。

•折断力(Break Force):为使此关节(Joint) 折断而需要应用的力。 超过该力会断掉与父物体的关系

•折断扭矩(Break Torque):为使此关节(Joint) 折断而需要应用的扭矩

•启动碰撞Enable Collision :如果启用,将启用与绑定物体之间的碰撞效果

撞门效果:谁撞门给谁

public class DoorForce : MonoBehaviour

{

    privatevoid OnCollisionStay(Collision other)

    {

       if(other.collider.tag == "Door")

       {   //在身体斜上方为门添加一个500的力  other.transform.GetComponent().AddForce((transform.forward+ transform.up)* 500);

        }

    }

}

固定关节Fixed Joint

固定关节将对象移动限制为依赖于其他对象。这在某种程度上类似于父子化,不过是通过物理而不是变换层级结构来实现。使用它们的最佳情况是在具有要方便地相互分离的对象,或是连接两个对象的移动而不进行父子化时。

固定关节组件属性:

属性:              功能:

连接体(ConnectedBody):对关节(Joint)所依赖的刚体(Rigidbody)的可选引用。如果未设置,则关节(Joint)连接到世界坐标。

折断力(BreakForce):为使此关节(Joint) 折断而需要应用的力。

折断扭矩(BreakTorque):为使此关节(Joint) 折断而需要应用的扭矩。

启动碰撞EnableCollision :如果启用,将启用与绑定物体之间的碰撞效果。

弹性关节 Spring Joint

弹簧关节将两个刚体(Rigidbody) 组合在一起,从而将其约束为如同通过弹簧连接一样进行移动效果。

弹性关节组件属性:

属性:                    功能:

连接体(ConnectedBody):对关节所依赖的刚体(Rigidbody) 的可选引用。

锚点(Anchor):对象局部坐标空间中定义关节中心的位置(静止时)。这不是将对象拉向的位置。

弹簧(Spring):弹簧的强度。

阻尼(Damper):弹簧在处于活动状态时缩减的量。

最小距离(MinDistance):大于此值的距离不会使弹簧激活。

最大距离(MaxDistance):小于此值的距离不会使弹簧激活。

折断力(BreakForce):为使此关节折断而需要应用的力。

折断扭矩(BreakTorque):为使此关节折断而需要应用的扭矩。

启动碰撞EnableCollision :如果启用,将启用与绑定物体之间的碰撞效果

给刚体添加力

•rigidbody.AddForce(Vector3.forward*500);

•//世界坐标前方(Z轴)方向添加一个500的力。

•rigidbody.AddForce(transform.forward*500);

•//自己的坐标前方(Z轴)方向添加一个500的力。

 

练习;子弹检测

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

 

public class Bullet : MonoBehaviour {

 

    // Use thisfor initialization

     RaycastHit hit;

    public LayerMask layer;

    private Vector3 targat;

 

    public float MoveSpeed =5;

 

    void Start ()

    {

        if (Physics.Raycast(transform.position,transform.forward, out hit, 500, layer))

        {

           targat =hit.point;

        }

        else

        {//如果没有检测到目标

            targat =transform.TransformPoint(0, 0, 500);

        }

    }

      

       // Update iscalled once per frame

       void Update ()

    {

       transform.position = Vector3.MoveTowards(transform.position, targat, Time.deltaTime *MoveSpeed);

        if((transform.position - targat).sqrMagnitude <= 0.1f)

        {

           Destroy(hit.transform.gameObject);

            Destroy(this.gameObject);

        }

       }

}

你可能感兴趣的:(Unity3d,基础入门)