Unity – Raycast 射線檢測

本文簡要分析了Unity中射線檢測的基本原理及用法,包括:

  • Ray 射線
  • RaycastHit 光線投射碰撞信息
  • Raycast 光線投射
  • SphereCast 球體投射
  • OverlapSphere 相交球等

項目地址Raycast – SouthBegonia



Ray 射線

  • 含義:官方解釋為一條無窮的線,開始於origin點,朝向direction方向(但是,根據項目驗證來看其默認長度為單位向量,只有對direction進行乘以倍率,才可實現延長射線,而非無窮)
  • 用法:
    • Ray ray = new Ray(transform.position,transform.forward):從物體中心創建一條指向前方的射線ray
    • Ray camerRay = Camera.main.ScreenPointToRay(Input.mousePosition):產生一條從攝像機產生、經過屏幕上光標的射線。當相機為perspective模式,射線在相機梯形視野內發散;若為orthoGraphic,則為垂直與相機面的直線段(見上圖)

RaycastHit 光線投射碰撞信息

  • 含義:取得從Raycast函數中得到的碰撞信息(注意不是collider哈,是包含collider信息)
  • 關鍵變量:point、collider、rigidbody、transform

檢測方法 – 線型檢測

Physics.Raycast 光線投射

  • 功能:在已有一條射線(也可無)的基礎上,使用射線(新建射線)進行一定距離內的定向檢測。可修改射線長度,限制其檢測的Layer層,並且可以得到射線檢測到的碰撞信息。但僅能檢測到第一個被射線碰撞的物體,後面的物體無法被檢測到
  • 用法:
    • Raycast(transform.position, Vector.forward, distance, LayerMask.GetMask("Enemy")): 從物體中心點起,朝向Vector3.forward方向發射一條射線,該射線長度為distance,射線可檢測到的層為Enemy層,返回bool類型
    • Raycast(transform.position, Vector.forward, distance, out RaycastHitInformation ,LayerMask.GetMask("Enemy")):從物體中心點起,朝向Vector3.forward方向發射一條射線,該射線長度為distance,將碰撞信息反饋到RaycastHitInformation上,射線可檢測到的層為Enemy層,返回bool類型
    • Raycast (MyRay, distance, LayerMash.GetMask("Enemy")):從已有的射線MyRay出發,長度延伸至distance,射線可檢測到的層為Enemy層,返回bool類型
    • Raycast (MyRay, out RaycastHitInformation, distance, LayerMask.GetMask("Enemy"))
  • 適用場合:配合相機坐標轉換實現各類交互

Physics.RaycastAll 所有光線投射

  • 功能:機理用法大致同Raycast,當區別在於可檢測射線路徑上的所有物體,返回檢測信息的數組。其他帶All後綴的方法也同理
  • 用法:
    • RaycastHit[] hits = RaycastAll(Vector3.zero, Vector.forward, distance, LayerMask.GetMask("Enemy"))
    • RaycastHit[] hits = RaycastAll(MyRay, distance, LayerMash.GetMask("Enemy"))
  • 適用場合:穿透性檢測

Physics.Linecast 線段投射

  • 功能:建立某兩點之間的射線進行檢測,返回bool類型
  • 用法:
    • Linecast(startPos, endPos, LayerMask.GetMask("Enemy"))
    • Linecast(startPos, endPos, out RaycastHit, LayerMask.GetMask("Enemy"))
  • 適用場合:特定地點局部距離射線檢測

檢測方法 – 體型檢測

Physics.SphereCast 球體投射

  • 功能:擴展檢測範圍為球形,返回bool類型。但是該投射用法需要萬分小心,見下
  • 用法:
    • SphereCast (originPos, radius, direction, out RaycastHit, distance, LayerMask.GetMask("Enemy")):含義是在originPos點創建半徑為radius的球體;以朝向direction方向的球面為起始面(另一面捨棄),移動distance距離,期間半球面經過的區域即為檢測區域。那麼originPos到originPos+radius內的半球區域呢?答案是捨棄,用官方的話來說,是邊界而不是包圍體。(立體結構:以左右球球心為軸線,建立半徑為radius、高為distance的圓柱體,左球挖去右半體積,右球添加右半體積)
    • SphereCast (Ray, radius, out RaycastHit, distance, LayerMask.GetMask("Enemy"))
  • 適用場合:檢測目的地是否可抵達,從而判斷可移動性

Physics.Boxcast 塊體投射/ CapsuleCast 膠囊體投射

  • 功能:同球體投射
  • 用法:同球體投射

Physics.OverlapSphere 相交球

  • 功能:同樣檢測球形,但與SphereCast存在較大區別
  • 用法:
    • Collider[] hits = Physics.OverlapSphere(startPos, radius, LayerMask.GetMask("Enemy")):以startPos為原點,創建半徑為radius的球形,檢測區域為整個球形包圍體(實心),檢測Enemy層上的物體,返回所有碰撞物體的collider而不是RaycastHit
  • 適用場合:檢測掛載物體球形範圍內是否存在碰撞,常用方法

Physics.IgnoreCollision 忽略碰撞

  • 功能:屏蔽兩個collider的碰撞,第三個參數為bool
  • 用法: IgnoreCollision (collider1, collider2, ignore)

參考