2016年7月4日 星期一

【Unity】使用3D與2D射線(Ray)來判斷物件

今天來提判斷被點擊物件的方式,射線(Ray)。
這次會分3D射線及2D射線,首先從比較常看到的3D射線開始吧。
Unity Ray
就如上圖看到,當滑鼠點擊到物件時,會顯示出物件的名稱,程式碼如下:
using UnityEngine;
public class RayTest : MonoBehaviour {
    void Update () {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Input.GetMouseButton(0) && Physics.Raycast(ray, out hit))
        {
            Debug.DrawLine(Camera.main.transform.position, hit.transform.position, Color.red, 0.1f, true);
            Debug.Log(hit.transform.name);
        }
    }
}
要注意被ray打到的物件需要有Collider。
射線ray從攝影機的位置出發,到滑鼠點擊的位置,而滑鼠點擊的座標位置,會透過ScreenPointToRay從螢幕座標轉換到三維座標。
hit是被射線ray打到的物體,當滑鼠點下並且射線有碰到物體時,
畫出攝影機到物體的線,並且顯示hit的名稱。
像這樣使用ray顯示物件的name或tag,就可以知道滑鼠點擊的物件是什麼。

以上是3D的射線,接下來是2D射線。
如果你的物件為2D而且碰撞器是Collider2D時,需要使用2D射線才會有效果。
Unity Ray
程式碼如下:
using UnityEngine;
public class RayTest : MonoBehaviour {
    void Update () {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Input.GetMouseButton(0))
        {
            RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, 10, -1); ;
            if (hit.collider)
            {
                Debug.DrawLine(ray.origin, hit.transform.position, Color.red, 0.1f, true);
                Debug.Log(hit.transform.name);
            }
        }
    }
}
基本上概念和3D射線差不多,要注意的是RaycastHit2D的地方,
和3D射線不同,2D射線的hit需要有初始位置、方向、距離及遮罩,
例如這裡的Physics2D.Raycast(ray.origin, ray.direction, 10, 0);
第一個參數為初始位置(origin),這裡給定射線的初始位置,接著方向(direction)為射線的方向。
再來的距離(distance)會直接影響射線能不能打到物體,像這裡距離為10,若超過這個距離射線就碰不到。
最後為遮罩(layerMask),只有該階層的layer會被2D射線偵測到,階層計算方式為2^layer階層,例如要偵測的layer為第8層,數值就為2的8次方,也就是256

以上就是3D和2D的射線(Ray),這次就到這裡。

6 則留言:

  1. 您好
    我使用您的方法判斷點擊事件
    請問有辦法可以點擊一次就只發送一次的點擊訊息嗎?
    每次我只點擊一次時
    程式自動偵測到我點擊很多次

    我的程式為:
    在手機上點擊畫面,點擊後開啟一個Panel。

    但是程式發送第一次點擊訊息開啟了Panel
    同時間也發送了好幾筆點擊訊息,此時就會跳出error 錯誤訊息: Panel已開啟
    但是我明明只點擊一次而已啊...
    所以想問問有沒有甚麼方法呢?
    謝謝

    回覆刪除
    回覆
    1. 把GetMouseButton替換成GetMouseButtonDown就行了

      刪除
  2. 用up比較好,因為down就代表滑鼠往下按,可能在點的時候還是會被偵測到很多次,但放開就是一次的

    回覆刪除
    回覆
    1. 這裡用GetMouseButton其實是為了讓結果看得清楚點
      但假如要偵測滑鼠按下或放開的那一刻
      使用GetMouseButtonDown或GetMouseButtonUp的確是比較合適
      謝謝你的建議

      刪除
  3. 您好 您的方法正确吧 我在Canvas下的button按钮 检测不到呀

    回覆刪除

【自製小遊戲】水平思考猜謎(海龜湯)

遊戲連結 海龜湯的玩法是由出題者提出一個難以理解的事件,參與猜題者可以提出任何問題以試圖縮小範圍並找出事件背後真正的原因。但出題者僅能以「是」、「不是」或「沒有關係」來回答問題。 本遊戲蒐集各種論壇、平台的42個題目,提供給想玩海龜湯卻愁找不到題目的你們。 ...