1-4 Using Raycasts To Query Click
本次要使用滑鼠偵測遊戲畫面中點擊到的物件屬於哪個Layer。首先,我們定義兩個Layer:
1. Walkable
2. Enemy
並考慮若滑鼠點擊的物件並未屬於任何我們所定義的Layer,便視為RaycastEndStop。
先隨意點擊場景中任一物件,並從Inspector視窗找到Layer選項。點開後,會看見Add Layer選項。
最後執行結果,會看見Console出現Walkable,這是因為目前介面上只有Walkable物件,後面再來新增Enemy。
1. Walkable
2. Enemy
並考慮若滑鼠點擊的物件並未屬於任何我們所定義的Layer,便視為RaycastEndStop。
先隨意點擊場景中任一物件,並從Inspector視窗找到Layer選項。點開後,會看見Add Layer選項。
進入Add Layer畫面後,請在User Layer 8 定義 Walkable,User Layer 9 定義 Enemy。
然後,我將場景中的物件都統一整理到Environment的Empty GameObject中(記得Environment的座標要reset唷)。接著,Environment底下所有物件的Layer都設定為Walkable。
(你可能會發現場景佈置跟上次不太一樣,我只是做了點變化啦,不要太在意哈哈。)
接下來,使用課程提供的CameraRaycaster.cs檔案:
using UnityEngine; public class CameraRaycaster : MonoBehaviour { //設定偵測Layer的順序,亦即先偵測Enemy,若沒有Enemy才偵測Walkable public Layer[] layerPriorities = { Layer.Enemy, Layer.Walkable }; //使用SerializeField屬性,該變數會出現於Inspector中,且同時為private [SerializeField] float distanceToBackground = 100f; Camera viewCamera; RaycastHit m_hit; public RaycastHit hit { get { return m_hit; } } Layer m_layerHit; public Layer layerHit { get { return m_layerHit; } } void Start() // TODO Awake? { viewCamera = Camera.main; } void Update() { // 從layerPriorities中依順序偵測 foreach (Layer layer in layerPriorities) { var hit = RaycastForLayer(layer); if (hit.HasValue) { m_hit = hit.Value; m_layerHit = layer; return; } } // 都沒偵測到,回傳RaycastEndStop m_hit.distance = distanceToBackground; m_layerHit = Layer.RaycastEndStop; } RaycastHit? RaycastForLayer(Layer layer) { int layerMask = 1 << (int)layer; // See Unity docs for mask formation Ray ray = viewCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; // used as an out parameter bool hasHit = Physics.Raycast(ray, out hit, distanceToBackground, layerMask); if (hasHit) { return hit; } return null; } }
你可以複製上面的程式碼,然後再自己新增。新增方式,請從Project中點擊右鍵,選擇Create/C# Script。
然後,我們還需要新增Utility.cs,新增完以後將Unity自動產生的程式碼刪除,並於Utility.cs中定義Layer:
public enum Layer{ Walkable = 8, Enemy = 9, RaycastEndStop = -1 }
接著就可以將CameraRaycaster.cs檔案拖曳到Camera Arm中了。
再從Camera Arm新增Cursor.cs,撰寫程式碼,從Camera Raycaster取得目前滑鼠點擊到的物件Layer。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Cursor : MonoBehaviour { CameraRaycaster cameraRaycaster; void Start () { //取得Camera Arm中的Camera Raycaster,因為Cursor.cs也是放在Camera Arm之下,故可以直接用GetComponent取得。 cameraRaycaster = GetComponent(); } void Update () { //於Console中顯示滑鼠點擊到的Layer print (cameraRaycaster.layerHit); } }
留言
張貼留言