射线即是从指定位置发射一条射线,检测与射线碰撞的物体。该方法通常应用在物体拾取,射击等功能。
ray的主要方法
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;
}