1. 程式人生 > >[Unity]Ray射線物理檢測碰撞和LayerMask的使用

[Unity]Ray射線物理檢測碰撞和LayerMask的使用

射線:射線是3D世界中一個點向一個方向發射的一條無終點的線,在發射軌跡中與其他物體發生碰撞時,它將停止發射 。
用途:在unity中射線應用範圍比較廣, 多用於碰撞檢測(如:子彈飛行是否擊中目標)、角色移動 等。

相關API

1、Ray Camera.main.ScreenPointToRay(Vector3 pos)   返回一條射線Ray從攝像機到螢幕指定一個點

2、Ray Camera.main.ViewportPointToRay(Vector3 pos)  返回一條射線Ray從攝像機到視口(視口之外無效)指定一個點

3、Ray 射線類 

4、RaycastHit 光線投射碰撞資訊

5、bool Physics.Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask)

    當光線投射與任何碰撞器交叉時為真,否則為假。

    bool Physics.Raycast(Ray ray, Vector3 direction, RaycastHit out hit, float distance, int layerMask)

    在場景中投下可與所有碰撞器碰撞的一條光線,並返回碰撞的細節資訊()。

    bool Physics.Raycast(Ray ray, float distance, int layerMask)

    當光線投射與任何碰撞器交叉時為真,否則為假。

    bool Physics.Raycast(Vector3 origin, Vector3 direction, RaycastHit out hit,float distance, int layerMask)

    當光線投射與任何碰撞器交叉時為真,否則為假。

    注意:如果從一個球型體的內部到外部用光線投射,返回為假。

    引數理解:

  origin : 在世界座標中射線的起始點

  direction: 射線的方向

  distance: 射線的長度

  hit: 使用c#中out關鍵字傳入一個空的碰撞資訊類,然後碰撞後賦值。可以得到碰撞物體的transform,rigidbody,point等資訊。 

  layerMask: 只選定Layermask層內的碰撞器,其它層內碰撞器忽略。 選擇性的碰撞

6、RaycastHit[] RaycastAll(Ray ray, float distance, int layerMask)

   投射一條光線並返回所有碰撞,也就是投射光線並返回一個RaycastHit[]結構體。

列子如下:
using
UnityEngine;
usingSystem.Collections;

publicclassRayTest : MonoBehaviour {

//Usethisforinitialization
voidStart ()
    {
mainCrma = Camera.main;
    }
privateCameramainCrma;
privateRaycastHitobjhit;
privateRay_ray;
voidUpdate () 
    {
if (Input.GetMouseButtonDown(0)) 
        {
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線,到點選的座標
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//顯示一條射線,只有在scene檢視中才能看到

if (Physics.Raycast (_rayoutobjhit100)) 
            {
GameObjectgameObj = objhit.collider.gameObject;

Debug.Log("Hit objname:"+gameObj.name+"Hit objlayer:"+gameObj.layer);
            }
        }
    }



圖片

layerMask引數: 

Raycast (ray : Ray, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers)

其實很簡單:1 << 10  開啟第10的層。

~(1 << 10) 開啟除了第10之外的層。

~(1 << 0) 開啟所有的層。

(1 << 10) | (1 << 8) 開啟第10和第8的層。

列子如下:
usingUnityEngine;
usingSystem.Collections;

publicclassLayerMaskTest : MonoBehaviour {

//Usethisforinitialization
voidStart () 
    {
mainCrma = Camera.main;
mask = 1<<( LayerMask.NameToLayer("cube"));//例項化mask到cube這個自定義的層級之上。
    }

//privateLayerMaskmask1<<10;
privateLayerMaskmask;
privateCameramainCrma;
privateRaycastHitobjhit;
privateRay_ray;
voidUpdate () 
    {
if (Input.GetMouseButtonDown(0)) 
        {
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線,到點選的座標
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//劃出射線,只有在scene檢視中才能看到

if (Physics.Raycast (_ray,outobjhit100mask.value))
            {
GameObjectgameObj = objhit.collider.gameObject;

Debug.Log("Hit objname:"+gameObj.name+"--Hit objlayerName:"+LayerMask.LayerToName (10));
            }

        }

    }
}
 
 建立2個cube,一個layer設定為:cube  一個layer設定為:Default
執行如下:
圖片