unity3d問題集對Physics.Raycast和Ray(射線)的理解

在遊戲中,我們常常要用到鼠標來控制物體的移動或是鼠標拾取某個物體。還有射擊遊戲裏,子彈打中靶子......這些都需要Physics.Raycast和ray。可見他們的重要性。

首先說說射線;

射線是3D世界中一個點向一個方向發射的一條無終點的線。在發射的軌跡中,一旦與其他物體發生碰撞,它就會停止。

在API文檔中Ray是一個結構體【Struct】

(對於沒有語言基礎的同學來說理解這個可能會比較吃力,可以暫時簡單理解成是unity人爲設計規定的一種數據類型,可以像int那樣使用它)

static function Ray (origin : Vector3, direction : Vector3) : Ray 【構造】

Origin: 射線的起點 direction:射線的方向 ;

具體參數變量請參考官方腳本文檔。

舉個例子吧。(下面會一一講解代碼)

//用鼠標拾取物體

 


鼠標碰到cube就會移動到另一個plane中。

 

這裏除了Ray還有Physics.Raycast,這兩者密不可分,下面 一 一闡述
(下面主要是解釋代碼,莫名其妙的地方聯繫代碼,跨度有點大,後來都忘了例子是什麼了QAQ)

剛剛接觸ray的時候感覺Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);有點不理解,只是記下來這句可以從攝像機發出一條射線,

那麼這條射線的源點在哪,又是沿什麼方向呢?

(體會:不理解或是第一次見的類、結構一定要親自查API文檔,並在腳本中試一試;看了文檔還是不理解就百度、問人)

文檔中說:產生的射線是在世界空間中,從相機的近裁剪面開始並穿過屏幕position(x,y)像素座標(position.z被忽略)。

那近裁面和屏幕是什麼關係呢?是無限接近嗎?不知道啊.....~~~(>_<)~~~ 有時間要好好研究一下攝像機!有人知道的話,請告訴我~

 


那麼爲什麼要把鼠標位置轉化爲屏幕位置呢?

 

因爲單位不一樣;

屏幕空間點用像素定義,屏幕的左下爲(0,0);右上是(PixelWidth,pixelHeight).Z的位置是以世界單位衡量的到相機的距離。是像素座標。

而攝像機的Vector3則是世界座標,所以需要把屏幕上的點轉化爲世界座標。

ScreenPointToRay()函數可以把屏幕像素座標變成一條射線。

下面說說Physics.Raycast()

API文檔中只給出這幾個方法:

public static bool Raycast(Ray ray, RaycastHit hitInfo, float distance, int layerMask);

public static bool Raycast(Ray ray, float distance, int layerMask);

public static bool Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask);

public static bool Raycast(Vector3 origin, Vector3 direction, RaycastHit , float distance ,int layerMask );

但是我在VS裏卻可以找到更多的方法(經常看到別人只用到了兩個變量,特意查了一下),如下圖:

 


不過我個人覺得還是用給的4個函數好點,因爲用4個參數可以很容易看出你的意圖,即代碼的可讀性會變高。

 

這裏說一下public static bool Raycast(Ray ray, RaycastHit hitInfo, float distance, int layerMask);

其他都差不多;

Ray ray是射線;RaycastHit hitInfo是碰撞信息;float distance是碰撞距離;int layerMask是碰撞的層

這4個參數,我一開始不太理解的地方是:RaycastHit hitInfo是用來記錄從raycast函數中得到的信息反饋。(out關鍵字,這個輸出參數不知道的話還是去補一下C#吧...)

這是什麼?沒概念!好抽象啊!什麼信息?誰的信息?有什麼用?

(是的,遇到unity定義的一些概念就會有些不理解,這很正常。而這些人爲定義的抽象概念,unity一般會用結構體來定義,而不是類,這也是struct和class的區別之一吧。和Vector3,Ray一樣,都是結構體,都是一些概念。)

下面就來看看RaycastHit是什麼鬼吧。

上面用拾取物體的例子先是申明瞭一個RaycastHit類型的hit變量,在Physics.Raycast()方法後,hit這個變量就攜帶了射線碰撞到那個物體的一些信息(這裏碰到的是方塊cube)。

這包括哪些信息呢?如圖:

 


(不知道的概念,自己寫一些簡單代碼去試試,會受益匪淺!)

 

而這裏就用hit得到了transform信息,有了cube的transform,我們不就可以控制它的移動了嗎。

也說一下int layerMask吧。

可以看到是int類型,我們之前申明並初始化了targetMask = LayerMask.GetMask("target");【這個方法在聖典的中文API中貌似沒有】

LayerMask.GetMask()方法就是把target層用返回一個對應的整數。

 


Vector3 offset = new Vector3(15, 0, 0);//設置cube要移動的距離;

 

hit.transform.position = hit.transform.position + offset;//移動cube;

Physics.Raycast(ray, out hit, 100f, targetMask)

總的來說,這句話的意思是:從攝像機發射一條射線,射線的範圍是100米,只和target層發生碰撞,碰撞後得到碰撞體的信息,並返回一個布爾值。

說的有些囉嗦了,今天就寫到這吧。
發佈的時候驗證碼錯誤,有重寫了一遍QAQ~~~強烈建議蠻牛博客+++自動保存~~~
寫文章不易,轉載請註明出處【Sugar丿miss丶QAQ】http://www.unitymanual.com/blog-42778.html



作者:Moment__格調
鏈接:https://www.jianshu.com/p/6ccd8e91e996
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章