• Unity入门08——核心系统02


    物理系统之碰撞检测

    1.刚体

    碰撞产生的必要条件:

    • 两个物体都有碰撞器 Collider
    • 至少一个物体有刚体

    RigidBody组件信息:

    1.Mass:质量       默认为千克,质量越大惯性越大

    2.Drag:空气阻力       根据力移动对象时影响空气阻力大小 ,0 表示没有空气阻力

    3.Augular Drag:旋转阻力       根据扭矩旋转对象时影响对象的空气阻力大小,0 表示没有阻力

    4.Use Gravity:是否受重力影响

    5.Is Kinematic:是否设置为运动学

            如果启用,对象将不会被物理引擎驱动,只能通过 Transform 对其进行操作,对于移动平台,或者如果要动画附加了 HingeJoint 的刚体,此属性将非常有用

    6.Interpolate:插值运算

    • None:不应用插值运算

    • Interpolate:根据前一帧的变换来平滑变换

    • Extrapolate:插值运算

      根据下一帧的估计变换来平滑变换,若物理帧时间过长,此效果将不好

    7.Collison Detection:碰撞检测模式

    • None:Discrete:离散检测

    • Interpolate:根据前一帧的变换来平滑变换

    • Discrete:离散检测

      对场景中的所有其他碰撞体使用离散碰撞检测,其他碰撞体在测试碰撞时会使用离散检测。用于正常碰撞(默认值)

    • Continuous:连续检测

      对动态碰撞体(具有刚体)使用离散碰撞检测

      对静态碰撞体(没有刚体)使用连续碰撞检测

      设置为连续动态的刚体,将在测试与该刚体的碰撞时使用连续碰撞检测(物理性能消耗较大,物体运动缓慢时请设置为 Discrete)

      其他刚体将使用离散碰撞检测

    • Continuous Dynamic:连续动态检测

      对设置为连续和连续动态碰撞的对象使用连续碰撞检测

      对静态碰撞体(没有刚体)使用连续碰撞检测

      对其他碰撞体使用离散碰撞检测

      用于快速移动的对象

    • Continuous Speculative:连续推测检测

      对刚体和碰撞体使用推测性连续碰撞检测

      通常比连续碰撞检测的成本更低

     无刚体碰撞盒DiscreteContinuousContinuous DynamicContinuous Speculative
    无刚体碰撞盒不检测碰撞DiscreteContinuousContinuousContinuous Speculative
    DiscreteDiscreteDiscreteDiscreteDiscreteContinuous Speculative
    ContinuousContinuousDiscreteDiscreteContinuousContinuous Speculative
    Continuous DynamicContinuousDiscreteContinuousContinuousContinuous Speculative
    Continuous SpeculativeContinuous SpeculativeContinuous SpeculativeContinuous SpeculativeContinuous SpeculativeContinuous Speculative

    性能消耗关系:Continuous Dynamic > Continuous Speculative > Continuous > Discrete 

    8.Constrains:对刚体运动的约束

    • Freeze Position:限制刚体在世界坐标轴下 X、Y、Z 轴的移动
    • Freeze Rotation:限制刚体在世界坐标轴下 X、Y、Z 轴的旋转

    9.Info:用于显示参数的面板,不修改里面的值

    2.碰撞器 Collider

    1.碰撞器种类 

    • 盒状碰撞器 Box Collider(常用)
    • 球状碰撞器 Sphere Collider(常用)
    • 胶囊碰撞器 Capsule Collider(常用)
    • 网格碰撞器 Mesh Collider
    • 轮胎碰撞器 Wheel Collider
    • 地形碰撞器 Terrain Collider

    2.共同参数 

    1. Is Trigger:是否为触发器

      如果启用,则该碰撞体用于触发事件,并被物理引擎所忽略

      主要用于进行没有物理效果的碰撞检测

    2. Material:物理材质

      可以确定碰撞体和其他对象碰撞时的交互(表现)方式

    3. Center:碰撞体的中心偏移位置

    3.常用碰撞器 

    1.Box Collider
            Size:碰撞体在 X、Y、Z 方向上的大小
    2.Sphere Collider
            Radius:球形碰撞体的半径大小
    3.Capsule Collider

    • Radius:胶囊体的半径
    • Height:胶囊体的高度
    • Direction:胶囊体在对象局部空间中的轴向

    4.异形物体使用多种碰撞器组合 

     刚体对象的子对象碰撞信息参与碰撞检测(即父物体添加 Rigid Body,子物体设置 Collider。)

    5.不常用碰撞器

    1.Mesh Collider

    • Convex:是否为凸面的

      勾选后,该 Mesh Collider 将会与其他 Mesh Collider 发生碰撞,最多支持 255 个三角面片

      如果该对象添加了刚体 Rigid Body,则该选项必须勾选,否则会报错

    • Cooking Options:物理引擎对网格的处理方式(不常用)
    • Mesh:引用需要用于碰撞的网格

    2.Wheel Collider

            赛车游戏中使用,其他时候不常用

            注意:添加 Wheel Collider 后一定要添加 Rigid Body(或在父物体添加),否则将失效

    3.Terrain Collider

            地形系统中使用

            性能较为低下,很少使用

    3.物理材质 

    在 Project 中创建物理材质 Physics Material 

     

    1.Dynamic Friction

    已在移动时使用的摩擦力。通常为О到1之间的值。值为零就像冰一样,值为1将使对象迅速静止(除非用很大的力或重力推动对象)

    2.Static Friction

    当对象静止在表面上时使用的摩擦力。通常为О到1之间的值。值为零就像冰一样,值为1将导致很难让对象移动。

    3.Bounciness

    表面的弹性如何?值为О将不会反弹。值为1将在反弹时不产生任何能量损失,预计会有一些近似值,但可能只会给模拟增加少量能量。

    4.Friction Combine(两个碰撞对象的摩擦力的组合方式。)

    • Average    对两个摩擦值求平均值。
    • Minimum   使用两个值中的最小值。
    • Maximum  使用两个值中的最大值。
    • Multiply      两个摩擦值相乘。

    5.unce Combine

    两个碰撞对象的弹性的组合方式。其模式与Friction Combine模式相同

    4.碰撞检测函数

    1.知识点回顾

    1. 如何让两个游戏物体之间产生碰撞(至少一个刚体 和 两个碰撞器)
    2. 如何让两个物体之间碰撞时表现出不同效果(物理材质)
    3. 触发器的作用是什么(让两个物体碰撞没有物理效果,只进行碰撞处理)

     注意:碰撞和触发响应函数 属于 特殊的生命周期函数 也是通过反射调用

    2.物理碰撞检测响应函数 

    1.碰撞触发接触时会 自动执行这个函数

    1. private void OnCollisionEnter(Collision collision)
    2. {
    3. //Collision类型的 参数 包含了 碰到自己的对象的相关信息
    4. //关键参数
    5. //1.碰撞到的对象碰撞器的信息
    6. //collision.collider
    7. //2.碰撞对象的依附对象(GameObject)
    8. //collision.gameObject
    9. //3.碰撞对象的依附对象的位置信息
    10. //collision.transform
    11. //4.触碰点数相关
    12. //collision.contactCount
    13. //接触点 具体的坐标
    14. //ContactPoint[] pos = collision.contacts;
    15. //只要得到了 碰撞到的对象的 任意一个信息 就可以得到它所有的信息
    16. print(this.name + "被" + collision.gameObject.name + "撞到了");
    17. }

    2.碰撞结束分离时 会自动执行的函数

    1. private void OnCollisionExit(Collision collision)
    2. {
    3. print(this.name + "被" + collision.gameObject.name + "结束碰撞了");
    4. }

     3.两个物体相互接触摩擦时 会不停的调用该函数

    1. private void OnCollisionStay(Collision collision)
    2. {
    3. print(this.name + "一直在和" + collision.gameObject.name + "接触");
    4. }

    3.触发器检测响应函数

    1.触发开始的函数 当第一次接触时 会自动调用

    1. private void OnTriggerEnter(Collider other)
    2. {
    3. print(this.name + "被" + other.gameObject.name + "触发了");
    4. }

     2.触发结束的函数 当水乳相融的状态结束的时 会调用一次

    1. private void OnTriggerExit(Collider other)
    2. {
    3. print(this.name + "和" + other.gameObject.name + "结束水乳相融的状态了");
    4. }

     3.当两个对象 水乳交融的时候 会不停调用

    1. private void OnTriggerStay(Collider other)
    2. {
    3. print(this.name + "正在和" + other.gameObject.name + "水乳相融");
    4. }

    4.要明确什么时候会响应函数 

    1. 只要挂载的对象 能和别的物体产生碰撞或者触发 那么对应的这6个函数 就能够被响应
    2. 6个函数不是说 我都得写 我们一般是根据需求来进行选择书写
    3. 如果是一个异形物体,刚体在父对象上,如果你想通过子对象上挂脚本检测碰撞是不行的 必须挂载到这个刚体父对象上才行
    4. 要明确 物理碰撞和触发器响应的区别

    5. 碰撞和触发器函数都可以写成虚函数 在子类去重写逻辑

    一般会把想要重写的 碰撞和触发函数 写成保护类型的 没有必要写成 public 因为不会自己手动调用

    都是Unity 通过反射帮助我们自动调用的

    5.刚体加力 

    1.刚体自带添加力的方法 

    给刚体加力的目标就是   让其有一个速度 朝向某一个方向移动

    1.首先应该获取刚体组件

    rigidBody = this.GetComponent();

    2.添加力

    1. 1.相对世界坐标
    2. 世界坐标系 z轴正方向加了一个力
    3. rigidBody.AddForce(Vector3.forward*10);
    4. 如果想要在 世界坐标系方法中 让对象 相对于自己的面朝向动
    5. rigidBody.AddForce(this.transform.forward * 10);
    6. 2.相对本地坐标
    7. 本地坐标系 z轴正方向加了一个力
    8. rigidBody.AddRelativeForce(Vector3.forward * 10);

    3.添加扭矩力,让其旋转

    1. 1.相对世界坐标
    2. 世界坐标系 y轴正方向加了一个力
    3. rigidBody.AddTorque(Vector3.up * 10);
    4. 2.相对本地坐标
    5. rigidBody.AddRelativeTorque(Vector3.up*10);

    4.直接改变速度

    1. 这个速度方向 是相对于 世界坐标系
    2. 如果要直接通过改变速度 来让其移动 一定要注意这一点
    3. rigidBody.velocity = Vector3.forward * 5;

    5.模拟爆炸的效果

    1. 参数一:力的大小
    2. 参数二:爆炸点
    3. 参数三:力的范围
    4. 模拟爆炸的力 一定是 所有希望产生爆炸效果影响的对象
    5. 都需要得到他们的刚体 来执行这个方法 才能都有效果
    6. rigidBody.AddExplosionForce(100, Vector3.zero,10);

     2.力的几种模式

    第二个参数 力的模式 主要的作用 就是 计算方式不同而已
    由于4种计算方式的不同 最终的移动速度就会不同
    rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);
     
    动量定理
    Ft = mv
    v = Ft/m
    F:力
    t:时间
    m:质量
    v:速度

    1. 1.Acceleration
    2. 给物体增加一个持续的加速度,忽略其质量
    3. v = Ft/m
    4. F(0,0,10)
    5. t:0.02s
    6. m:默认为1
    7. v = 10*0.02/1 =0.2m/s
    8. 每物理帧移动0.2m/s*0.02s=0.004m
    9. 2.Force
    10. 给物体添加一个持续的力,与物体的质量有关
    11. v = Ft/m
    12. F:(0,0,10)
    13. t:0.02s
    14. m:2kg
    15. v = 10*0.02s/2kg = 0.1m/s
    16. 每物理帧移动 0.1m/s*0.02s = 0.002m
    17. 3.Impulse
    18. 给物体添加一个瞬间的力,与物体的质量有关,忽略时间 默认为1
    19. v = Ft/m
    20. F:(0,0,10)
    21. t:默认为1
    22. m:2kg
    23. v = 10*1/2kg = 5m/s
    24. 每物理帧移动 5m/s*0.02s = 0.1m
    25. 4.VelocityChange
    26. 给物体添加一个瞬时速度,忽略时间、质量
    27. v = Ft/m
    28. F:(0,0,10)
    29. t:默认为1
    30. m:默认为1
    31. v = 10*1/1kg = 10m/s
    32. 每物理帧移动 10m/s*0.02s = 0.2m

    3.力场脚本 

    Constant Force

    给物体一个持续的力

    4.刚体的休眠

    1. 获取刚体是否处于休眠状态 如果是休眠状态就唤醒它
    2. if (rigidBody.IsSleeping())
    3. {
    4. //唤醒
    5. rigidBody.WakeUp();
    6. }
  • 相关阅读:
    Python函数的参数与返回值
    人生的开始
    K8S 实用工具之三 - 图形化 UI Lens
    百度网盘开放接口
    什么是Docker和Docker-Compose?
    数据可视化 | Tableau从入门到高手 入门&联接关系&数据预处理
    wpf窗体背景添加径向渐变效果实现
    运维自动化之账单系统
    珠海金山面试复盘
    Django反向解析函数reverse与resolve
  • 原文地址:https://blog.csdn.net/weixin_45274937/article/details/126726020