天天看點

Unity_腳本和實體系統的結合使用_011

Unity内置了NVIDIA的Physx實體引擎,Physx是目前使用最為廣泛的實體引擎,被很多遊戲大作所采用,開發者可以通過實體引擎高效、逼真地模拟剛體碰撞、車輛駕駛、布料、重力等實體效果,使遊戲畫面更加真實而生動。

Rigidbody(剛體)元件可使遊戲對象在實體系統的控制下來運動,剛體可接受外力與扭矩力用來保證遊戲對象像在真實世界中那樣進行運動。任何遊戲對象隻有添加了剛體元件才能受到重力的影響,通過腳本為遊戲對象添加的作用力以及通過NVIDIA實體引擎與其他的遊戲對象發生互動的運算都需要遊戲對象添加了剛體元件。

Rigidbody介紹

給物體添加剛體的方式如下圖:

Unity_腳本和實體系統的結合使用_011

RigidBody中的一些屬性

Unity_腳本和實體系統的結合使用_011

Mass 品質

Angular Drag 角阻力

可用來減緩物體的旋轉。阻力越高旋轉越慢。

Use Gravity 是否使用重力

Is Kinmatic 是否使用運動學

如果Use Gravity和Is Kinmatic同時勾選的話,那麼Is Kinmatic的優先級比Use Gravity要高

Interpolate

Collision Detection 碰撞檢測

Constraints 限制

Freeze Position 當機位置

Freeze Rotation 當機旋轉

我們在遊戲場景中添加基本的遊戲對象後,比如添加Cube後,是沒有上任何的效果的。隻有當我們給Cube添加Rigidbody元件後,運作程式,那麼Cube就會向下掉。這時候就是因為有了重力的影響。

碰撞器

盒子碰撞器 BoxCollider

球形碰撞器 SphereCollider

膠囊碰撞器 CapsuleCollider

【注意】膠囊體和圓柱體的碰撞器都是CapsuleCollider

【幾種碰撞器的性能比較】

碰撞檢測的條件

兩個物體要想發生碰撞兩者必須都有Collider元件,主動方必須要有剛體元件

相關代碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriggerDemo : MonoBehaviour {
    //collision指的是和綁定此腳本遊戲對象發生碰撞的遊戲對象
    //OnCollisionEnter在兩個遊戲對象發生碰撞的時候出發 一次碰撞隻出發一次
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("開始發生碰撞"+ collision.collider.name);
    }
    //OnCollisionStay在兩個遊戲對象碰撞過程中執行  一次碰撞大約執行20次左右
    private void OnCollisionStay(Collision collision)
    {
        Debug.Log("發生碰撞中");
    }
    //OnCollisionExit在兩個遊戲對象從接觸狀态開始分離的那一刻執行 再離開的瞬間 隻執行一次
    private void OnCollisionExit(Collision collision)
    {
        Debug.Log("準備結束碰撞");
    }
}
           

觸發器

其實就是碰撞器中,在檢測觸發的遊戲對象上Collider元件中勾選IsTrigger就行了。這樣的話,兩個遊戲對象就可以此互相穿越。

在主動方或者被動方對象上添加Rigidbody都可以

如何檢測一個物體已經碰到另一個物體了呢?

代碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriggerDemo : MonoBehaviour {
    //other表示的是和綁定此腳本的遊戲對象發生碰撞的遊戲對象
    //在兩個遊戲對象接觸的時候執行
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("開始進入"+ other.gameObject.name);
    }
    //在兩個遊戲對象有交集的時候執行
    private void OnTriggerStay(Collider other)
    {
        Debug.Log("進入" + other.gameObject.name);
    }
    //在遊戲對象互相分開的時候有交集
    private void OnTriggerExit(Collider other)
    {
        Debug.Log("準備出來" + other.gameObject.name);
    }
}
           

穿越的問題

在控制一個物體A去撞另一個物體B時,不要直接去修改物體A的Transform的position屬性,因為你會發現如果即使兩者發生了碰撞也還是會穿越的,原因就在于我們是直接設定的坐标,如果物體A有剛體元件的話,應該用AddForce,給物體添加一個力,然後讓實體引擎去讓物體動,此時如果發生了碰撞的話,就不會穿越了。

但是這樣需要注意的一點是 我們需要設定如下的參數 否則在添加力的情況下也是沒有效果的

Unity_腳本和實體系統的結合使用_011

做了上面的操作後我們可以通過控制transform.translate方法,Speed =1000m/s的時候依然不會檢測到碰撞

如果不是特别高的運作速度,建議還是不要調整此參數了,畢竟這樣持續檢測很好性能的。

Force系列方法

Rigidbody.AddForce

Rigidbody.AddRelativeForce

Toque系列方法

Rigidbody.AddTorque

Rigidbody.AddRelativeTorque

角色控制器CharacterController

Move

角色移動隻受到碰撞的限制。角色遇到碰撞時将會沿着碰撞盒滑動(你懂得)。傳回值是對移動過程中遇到的碰撞資訊的彙總。Move函數并不使用重力。

SimpleMove

簡單移動(會自動模拟重力)

Y軸的速度将會被忽略。速度機關是米每秒。重力自動生效。傳回值是角色是否着地。

實體射線Ray

RaycastHit

Physics.Raycast

射線可以分層通路