unity ray射線說明, 及使用ray拾取物體的方法。
阿新 • • 發佈:2019-01-05
Ray射線的說明
射線即是從指定位置發射一條射線,檢測與射線碰撞的物體。該方法通常應用在物體拾取,射擊等功能。
ray的主要方法
Ray、RaycastHit 、Raycast
RaycastHit用於儲存射線碰撞到的第一個物件資訊,
Raycast 用於檢測碰撞
RaycastHit[] RaycastAll(Ray ray, float distance, int layerMask) 獲取所有碰撞物體
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance);
ray:射線
hitinfo:這條射線所碰撞物體的資訊,使用out 用於返回
maxDistance:這條射線的最大距離;以射線ray經過的maxDistance長度之內,與第一個物件進行的物理碰撞的資訊儲存在hitInfo中;如果有碰撞物體,返回true, 沒有反false;
Ray從某處向滑鼠位置發射一條射線1。
Ray(Vector3 origin, Vector3 direction)
if(Input.GetMouseButton(0)){
// 獲取螢幕中點選的點
Ray myRay=Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(myRay,out hitInfo)){
// 如果點選了某個點,就用這個點減去發射者位置,得到新的向量
Vector3 direction =hitInfo.point-player.transform.position;
// 從發射物體,發射射線
Ray newray=new Ray(player.transform.position,direction);
Debug.DrawLine (newray.origin,hitInfo.point);
print("hit");
//hitInfo.collider.gameObject.tag=="animy"
if(hitInfo.transform.CompareTag("animy")){
print("animy");
}
}
}
Ray從某處向滑鼠位置發射一條射線 2 2017.2版本。
Ray myRay=RectTransformUtility.ScreenPointToRay(Camera.main, Input.mousePosition);
從攝像機 向滑鼠位置發射一條射線。
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
從某物體發射一條向前的射線
在指令碼中輸入Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd,out hit,1))
Debug.DrawLine(transform.position,hit.point,Color.red);
其中,Physics.Raycast(transform.position, fwd,out hit,1)為發射射線函式,transform.position為射線原點,fwd為發射方向,1為距離。
如果前方有碰撞體,則發射射線。
拾取物體
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mainRay : MonoBehaviour {
private GameObject pickGameObj=null;
//從攝像機到 滑鼠位置發出射線
private Ray ray;
//獲取射線資訊
private RaycastHit hitInfo;
// Update is called once per frame
void Update () {
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
// rayDrag("plane","boot");
// rayPick("plane","boot");
rayFlow("plane","boot");
}
//點選拾取,再點選釋放
void rayPick(string planeTag,string targetTag){
if(pickGameObj==null){
if(Input.GetMouseButtonDown(0)){
if(Physics.Raycast(ray,out hitInfo)){
if(hitInfo.collider.gameObject.tag==targetTag){
pickGameObj=hitInfo.collider.gameObject;
}
}
}
}else{
if(Physics.Raycast(ray,out hitInfo)){
if(hitInfo.collider.gameObject.tag==planeTag){
pickGameObj.transform.position=hitInfo.point;
}
}
if(Input.GetMouseButtonDown(0)){
pickGameObj=null;
}
}
}
//直接跟隨
void rayFlow(string planeTag,string targetTag){
GameObject gameObj=GameObject.FindGameObjectWithTag(targetTag);
if(Physics.Raycast(ray,out hitInfo)){
GameObject planeGameObj=hitInfo.collider.gameObject;
if(planeGameObj.tag==planeTag){
gameObj.transform.position=hitInfo.point;
}
}
}
//拖拽
void rayDrag(string planeTag,string targetTag){
if(Input.GetMouseButton(0)){
if(Physics.Raycast(ray,out hitInfo)){
//輔助檢視射線,只能在scene檢視看到 origin 原點,direction方向,distance長度,layermask層。
Debug.DrawLine(ray.origin,hitInfo.point);
// 獲取發生碰撞的物件
if(hitInfo.collider.gameObject.tag ==targetTag){
// 儲存被抓取的物件
pickGameObj=hitInfo.collider.gameObject;
}
}
}
//如果有拾取的物體,並且滑鼠與地面碰撞,則使物體移動
if(pickGameObj!=null){
if(Physics.Raycast(ray,out hitInfo)){
//與下句相同
//hitInfo.transform.GompareTag("somemeshTag")
if(hitInfo.collider.gameObject.tag ==planeTag){
pickGameObj.transform.position=hitInfo.point;
}
}
}
//釋放物體
if(Input.GetMouseButtonUp(0)){
pickGameObj=null;
}
}
void shoot(){
if(Input.GetMouseButton(0)){
Ray myRay=Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(myRay,out hitInfo)){
Vector3 direction =hitInfo.point-player.transform.position;
Ray newray=new Ray(player.transform.position,direction);
Debug.DrawLine(newray.origin,hitInfo.point);
print("hit");
//hitInfo.collider.gameObject.tag=="animy"
if(hitInfo.transform.CompareTag("animy")){
print("animy");
}
}
}
}
}
座標轉換
http://www.bubuko.com/infodetail-1292358.html
世界空間中的點座標轉換到螢幕座標:
screenPos = RectTransformUtility.WorldToScreenPoint(cam, worldPos.transform.position);
UGUI物體的座標轉換到螢幕座標:
screenPos = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, uguiObj.transform.position);
螢幕座標轉換到UGUI座標:
Vector3 worldPoint;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTrans, camPos, canvas.worldCamera,out worldPoint))
{
transform.position = worldPoint;
}
螢幕座標轉換到世界空間座標(射線碰撞位置):
var ray = RectTransformUtility.ScreenPointToRay(worldCamera, screenPos);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
pos.transform.position = hitInfo.point;
}