zoukankan      html  css  js  c++  java
  • Unity3D实践系列09, 物理引擎与碰撞检测

    在Unity3D中,一个物体通常包含一个Collider和一个Rigidbody。Collider是碰撞体,一个物体是Collider,才可以进行碰撞检测。Collider组件中的"Is Trigger"属性项被勾选上时,这个物体就变成碰撞检测体。

    物体有了Rigidbody组件,才会具备一些物理属性,比如重量、阻力、旋转阻力,等等。"Use Gravity"项表示是否有自然引力。"Is Kinematic"项表示是否被物理引擎所驱动,勾选上表示不受物理引擎所驱动。"Interpolate"项表示计算差值。"Collision Detection"项表示碰撞检测的频率,"Discrete"表示不连续检测,"Continuous"表示连续检测。


    用脚本来控制组件

     

    物理引擎是可以用脚本来控制的,现在用脚本来控制一些物理属性。

    一个Cube已经有了"Box Collider",没有"Rigidbody"组件,为其附加一个名称为"PhysicController"的脚本。

    using UnityEngine;
    
    using System.Collections;
    
    [RequireComponent(typeof(Rigidbody))]
    
    public class PhysicController : MonoBehaviour
    
    {
    
        public Rigidbody rb;
    
        // Use this for initialization
    
        void Start ()
    
        {
    
            rb = gameObject.GetComponent<Rigidbody>();
    
        }
    
        
    
        // Update is called once per frame
    
        void Update () {
    
        
    
        }
    
    }
    

    这时,自动为Cube添加了一个"Rigidbody"组件。

    27

    现在,给物体添加一个力,通过Rigidbody的AddForce实例方法就可以实现。修改"PhysicController"脚本如下:

    using UnityEngine;
    
    using System.Collections;
    
    [RequireComponent(typeof(Rigidbody))]
    
    public class PhysicController : MonoBehaviour
    
    {
    
        public Rigidbody rb;
    
        // Use this for initialization
    
        void Start ()
    
        {
    
            rb = gameObject.GetComponent<Rigidbody>();
    
            rb.AddForce(0,0,1,ForceMode.Impulse);
    
        }
    
        
    
        // Update is called once per frame
    
        void Update () {
    
        
    
        }
    
    }
    

    把当前"Rigidbody"的"Use Gravity"的勾选去掉。

    保存运行游戏,"Scene"中的Cube会带着某种程度的力在z轴方向移动。

    我们看到,在"PhysicController"脚本中用到了一个ForceMode枚举,该枚举的选项包括:Acceleration, Force, Impulse,VelocityChange。用"A"表示"Acceleration",用"F"表示"Force",用"I"表示"Impulse",用"V"表示"VelocityChange",用"M"表示物体,用"T"表示事件,之间的关系有2个:

    F = M * A
    I = F * T = M * V

    当ForceMode的项选择是"Acceleration"时,一般放在FixedUpdate方法中。修改"PhysicController"脚本如下:

    using UnityEngine;
    
    using System.Collections;
    
    [RequireComponent(typeof(Rigidbody))]
    
    public class PhysicController : MonoBehaviour
    
    {
    
        public Rigidbody rb;
    
        // Use this for initialization
    
        void Start ()
    
        {
    
            rb = gameObject.GetComponent<Rigidbody>();
    
            //rb.AddForce(0,0,1,ForceMode.Impulse);
    
        }
    
        
    
        // Update is called once per frame
    
        void Update () {
    
        
    
        }
    
        void FixedUpdate()
    
        {
    
            rb.AddForce(0, 0, 1, ForceMode.Acceleration);
    
        }
    
    }
    

    保存运行游戏,可以看到Cube是以加速度的方式在z轴方向平移,平移速度越来越快。

    物体之间的碰撞检测关系

     

    碰撞体的类型包括以下6个:

    ● Static Collider 静态碰撞器
    ● Rigidbody Collider 刚体碰撞器
    ● Kinematic Rigidbody Collider 运动学碰撞器
    ● Static Trigger Collider 静态触发碰撞器
    ● Rigidbody Trigger Collider 刚体触发碰撞器
    ● Kinematic Rigidbody Trigger Collider 运动学刚体触发碰撞器

    这6类碰撞器碰撞关系如下,打勾表示可以发生碰撞。

    28

    可见,

    ● 静态碰撞器只和刚体碰撞器发生碰撞
    ● 去碰撞的一方必须有Rigidbody,被碰撞的一方是可以没有Rigidbody的
    ● 物体被勾选上触发器,才会调用OnTrigger方法

    以下的打勾列举了触发发生的情况:

    29

    OnTrigger方法与OnCollision方法

    OnTriggerEnter()当Collider进入trigger时调用
    OnTriggerExit() 当Collider停止触发trigger时调用
    OnTriggerStaty() 当Collider解除trigger时,将在每一帧被调用

    OnCollisonEnter() 当collider/rigidbody触发另一个rigidbody/collider时被调用
    OnCollisionExit() 当collider/rigidbody停止触发另一个rigidbody/collider时被调用
    OnCollisionStay() 当collider/rigidbody触发另一个rigidbody/collider时,将在每一帧被调用

  • 相关阅读:
    使用 suspend 和 resume 暂停和恢复线程
    在 Go 语言中使用 Session(一)
    理解Cookie和Session
    Go Iris 中间件
    Go 通道(channel)与协程间通信
    Java终止线程的三种方式
    Go http包执行流程
    Java项目服务器跨域设置
    mysql5.7初始化密码报错 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before
    记录下在阿里云linux上安装与配置Mysql
  • 原文地址:https://www.cnblogs.com/darrenji/p/4601696.html
Copyright © 2011-2022 走看看