射線在unity中是個很方便的東西,對對象查找、多用於碰撞檢測(如:子彈飛行是否擊中目標)、角色移動等提供了很大的幫助,在此做個總結與大家分享下 ,若有不足歡迎吐槽
好了,話補多說啦,直接進入主題:
射線:在unity中射線是由一個點向一個方向發射的一條無終點的線,在發射軌跡中與其他物體發生碰撞時,它將停止發射 。
相關API:
1、Ray Camera.main.ScreenPointToRay(Vector3 pos) 返回一條射線Ray從攝像機到屏幕指定一個點
2、Ray Camera.main.ViewportPointToRay(Vector3 pos) 返回一條射線Ray從攝像機到視口(視口之外無效)指定一個點
3、Ray 射線類
4、RaycastHit 光線投射碰撞信息
5、bool Physics.Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask)
當光線投射與任何碰撞器交叉時為真,否則為假。
bool Physics.Raycast(Ray ray, Vector3 direction, RaycastHit out hit, float distance, int layerMask)
在場景中投下可與所有碰撞器碰撞的一條光線,並返回碰撞的細節信息()。
bool Physics.Raycast(Ray ray, float distance, int layerMask)
當光線投射與任何碰撞器交叉時為真,否則為假。
bool Physics.Raycast(Vector3 origin, Vector3 direction, RaycastHit out hit,float distance, int layerMask)
當光線投射與任何碰撞器交叉時為真,否則為假。
注意:如果從一個球型體的內部到外部用光線投射,返回為假。
參數理解:
origin : 在世界坐標中射線的起始點
direction: 射線的方向
distance: 射線的長度
hit: 使用c#中out關鍵字傳入一個空的碰撞信息類,然后碰撞后賦值。可以得到碰撞物體的transform,rigidbody,point等信息。
layerMask: 只選定Layermask層內的碰撞器,其它層內碰撞器忽略。 選擇性的碰撞
6、RaycastHit[] RaycastAll(Ray ray, float distance, int layerMask)
投射一條光線並返回所有碰撞,也就是投射光線並返回一個RaycastHit[]結構體。
列子如下:
using UnityEngine;
using System.Collections;
public class RayTest : MonoBehaviour {
// Use this for initialization
void Start ()
{
mainCrma = Camera.main;
}
private Camera mainCrma;
private RaycastHit objhit;
private Ray _ray;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線,到點擊的坐標
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//顯示一條射線,只有在scene視圖中才能看到
if (Physics.Raycast (_ray, out objhit, 100))
{
GameObject gameObj = objhit.collider.gameObject;
Debug.Log("Hit objname:"+gameObj.name+"Hit objlayer:"+gameObj.layer);
}
}
}
}
layerMask參數:
Raycast (ray : Ray, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers)
其實很簡單:1 << 10 打開第10的層。
~(1 << 10) 打開除了第10之外的層。
~(1 << 0) 打開所有的層。
(1 << 10) | (1 << 8) 打開第10和第8的層。
列子如下:
using UnityEngine;
using System.Collections;
public class LayerMaskTest : MonoBehaviour {
// Use this for initialization
void Start ()
{
mainCrma = Camera.main;
mask = 1<<( LayerMask.NameToLayer("cube"));//實例化mask到cube這個自定義的層級之上。
}
//private LayerMask mask 1<<10;
private LayerMask mask;
private Camera mainCrma;
private RaycastHit objhit;
private Ray _ray;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線,到點擊的坐標
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//划出射線,只有在scene視圖中才能看到
if (Physics.Raycast (_ray,out objhit, 100, mask.value))
{
GameObject gameObj = objhit.collider.gameObject;
Debug.Log("Hit objname:"+gameObj.name+"--Hit objlayerName:"+LayerMask.LayerToName (10));
}
}
}
}
創建2個cube,一個layer設置為:cube 一個layer設置為:Default
運行如下:
=============================
Ray只有起點和方向.函數附加x距離內的條件。
用到的Raycast主要有兩個:
Physics.Raycast:
作用於任何物體,可以加限定 只檢測某layer層
RaycastHit hit;
if(Physics.Raycast(transform.position, Vector3.down,out hit, 1000f))
print("dawdddd");
RaycastHit hit;
if(Physics.Raycast(transform.position, Vector3.down,out hit, 1000f,8))
print("dawdddd");
Collider.Raycast:
只檢測ray是否穿過該Collider
RaycastHit hit;
Ray ray= new Ray(transform.position,Vector3.down);
if(collider.Raycast(ray,out hit,100))
print("dawdddd");
注意:
(1)無論是哪種raycast檢測,從物體內部穿到外面的,都不視為穿過。只有從物體外穿到里面的才視為穿過。
(2)可以繪制 可見線 來輔助開發
1.Debug.DrawLine(V3 start,V3 end);
2. Gizmos.DrawLine (可以在編輯模式下顯示,可視化更強)
如果在scene的Gizmos選項下 勾選 3D Gizmos, 那么線段位於真實3D空間里,有前后遮擋。
如果不勾選,則gizmo永遠在最前顯示。
void OnDrawGizmos () {
Vector3 checkPos_a =transform.position + new Vector3(0,0,0.2f);
Gizmos.color = Color.green;
Gizmos.DrawLine(checkPos_a,checkPos_a + Vector3.down*15);
}
unity 檢測碰撞;unity射線使用;unity加碰撞;unity射線檢測碰撞;射線檢測unity;unity射線坐標;unity raycast layer;unity 查找所有子物體;unity 射線從自身發射;unity碰撞檢測;unity 碰撞檢測 沒反應;unity 點 射線;unity中的射線;unity射線移動;unity碰撞;碰撞點 unity;unity產生碰撞;unity碰撞之后;unity碰撞后不移動;unity 射線碰撞檢測;unity 射線檢測 范圍;unity 坐標射線;unity layer raycast;unity查找子物體;unity發射射線
