unity射线使用方法详解
目錄
射線的編程方法
射線的碰撞信息
穿過多個物體的射線?
獲取圖層的方法?
區域覆蓋型射線(Overlap)
射線的調試方法?
射線在游戲開發中,應用非常廣泛,所以掌握射線非常重要。
列如:判斷角色是否著地,可以向角色腳下發射射線,判斷是否接觸地面。
注意:各種射線檢測都是以物理系統為基礎的。射線需要與碰撞體和觸發器配合才能發揮出作用。
射線與視線一樣會被障礙物阻擋并且射線不僅可以有長度,還可以有粗細和形狀,列如球形射線,盒子射線和膠囊體射線。方法都大同小異。
射線的編程方法
常用的直線射線類型用類型Ray表示,Ray包含了起點origin跟方向direction的定義,起點和方向都用Vector3類型表示,前者是一個坐標,后者是一個表示方向的向量。
Vector3 origin = transform.position; Vector3 direction = Vector3.down; Ray ray = new Ray(origin, direction);在游戲中發射一條射線,最常用的是physics.Raycast()和physics.RaycastAll(),前者只能檢測一個碰撞體而被返回,后者可以一起檢測多個碰撞體。我們先講講Raycast(),常用的重載方法如下
bool raycast =Physics.Raycast(ray.origin,ray.direction,out RaycastHit hitInfo,float maxDistance,int layerMask);這里有五個參數,第一個是發射起點,第二個是發射方向,第三個是發射距離,第四個是射線碰撞信息,第五個是發射圖層,只檢測指定圖層,而忽略其他圖層,最后返回值bool是是否擊中某個碰撞體或者觸發器。其中,前兩個參數是必須,后三個參數根據我們的需要可加可不加。
射線的碰撞信息
我們再重點講講第三個參數RaycastHit,若沒有這個參數,我們的返回值僅僅只是“是否碰到了物體”,而無法確定碰撞點在哪,也不知道碰撞體是哪一個。射線檢測其實有著非常豐富的碰撞信息,如可以獲得其碰撞坐標,信息,以及法線。這些豐富的信息都被保存在RaycastHit結構體中。
綜合用法演示如下:
//聲明變量,用于保存信息RaycastHit hitInfo;//發射射線,起點是當前物體位置,方向是世界前方if(Physics.Raycast(transform.position,Vector3.forward,out hitInfo)){//如果碰到物體,運行此處,返回的是bOOl值//獲取碰撞點坐標Vector3 point = hitInfo.point;//獲取對方碰撞體組件Collider coll = hitInfo.collider;//獲取對方的Transgorm組件Transform trans = hitInfo.transform;//獲取對方的物體名稱string name = hitInfo.collider.name;//獲取碰撞點的法線向量Vector3 normal = hitInfo.normal;}注意,2D游戲跟3D游戲獲取碰撞體的方式有些不一樣,具體對比如下
//聲明變量,將碰撞信息直接賦值給變量RaycastHit2D hitInfo=Physics2D.Raycast(transform.position,Vector3.forward);//發射射線,起點是當前物體位置,方向是世界前方if(hitInfo.collider != null){//如果檢測的碰撞體不為空,運行此處。//獲取碰撞點坐標Vector3 point = hitInfo.point;//獲取對方碰撞體組件Collider coll = hitInfo.collider;//獲取對方的Transgorm組件Transform trans = hitInfo.transform;//獲取對方的物體名稱string name = hitInfo.collider.name;//獲取碰撞點的法線向量Vector3 normal = hitInfo.normal;}穿過多個物體的射線?
前面我們提到了Raycast()跟RaycastAll的區別,,區別是前者只能檢測一個碰撞體便返回,后者是能可以獲取到射線沿途碰到的所有信息(在指定圖層內)。我們以2D為例,差異看圖
如圖,圓形物體發射的射線被綠色碰撞體阻擋,無法到達藍色碰撞體,所以此時射線只能檢測綠色圖層,但不能檢測藍色碰撞體,那我們怎么能即檢測綠色碰撞體又能檢測藍色碰撞體。這時就需要我們使用Physics,RaycastAll(),該函數的返回值是RaycastHit數組。重載方式如下:
RaycastHit[] hit = Physics.RaycastAll(Vector3 origin,Vector3 direction,float maxDistance,int LayerMask);利用此函數,我們便可以實現同時檢測綠色,藍色兩個碰撞體,效果如下
?例子代碼,僅供參考
RaycastHit2D[] hitInfo = Physics2D.RaycastAll(ray.origin,ray.direction,10f,LayerMask.GetMask("ground","war")); for(i=0;i<hitInfo.Length;i++) {Debug.DrawLine( ray.origin,hitInfo[i].point ,Color.red);Debug.Log(hitInfo[i].collider.name); }獲取圖層的方法?
其中介紹一一個小知識,這里獲取圖層的方法是LayerMask.GetMask(),這里可獲得一個圖層或者多個圖層
例如獲得Ground,player,obstacle者三個層,代碼如下
int mask = layerMask.GetMask("ground","player","obstacle");區域覆蓋型射線(Overlap)
有時候需要檢測一個空間的范圍,例如炸彈爆炸時,范圍十米之內的物體都會受到波及,那么這里需要的不是一條射線,而是一個半徑為10米的球形區域。物理系統也提供了這類函數,它們均已Physics。Overlap開頭,這里以球形區域為例:
Collider[] collider = overlapSphere(Vector3 position,float radius,int LayerMask);第一個參數是位置,第二個參數是范圍距離,第三個是圖層,且該返回值是collider。
射線的調試方法?
利用Debug調試
在游戲開發中,射線的調試方法非常重要,可以將看不見的射線以可視化的形式表現出來,方便我們查看數據是否正確。這個方法是使用Debug.DrawLine()函數和Debug.DrawRay().
? ? 效果圖可以看上面,都有涉及使用到。需要說明的是在默認的情況下,該輔助線僅在編輯器的場景窗口可見,如果要在game窗口看到,則需要單機Game窗口右上角的Gizmos開關。
?利用Gizmos
調用OnDrawGizmos()函數或OnDrawGizmosSelected,它們同樣都可以用來繪制輔助圖標。區別在于
函數OnDrawGizmos()在程序一運行就執行,之后每幀都在執行,
函數OnDrawGizmosSelected()在鼠標點擊到腳本掛載的物體的身上的時候運行,不管有多少父類對象,它都會執行。
這里推薦使用OnDrawGizmosSelected()
范例如下
private void OnDrawGizmosSelected(){Gizmos.DrawLine(Vector3 from, Vector3 to);Gizmos.DrawRay((Vector3 from, Vector3 direction);}可在scence窗口查看輔助線,同樣想在game窗口可以看到,則需要單機Game窗口右上角的Gizmos開關。
總結
以上是生活随笔為你收集整理的unity射线使用方法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unity射线点击移动
- 下一篇: Unity的射线