Ray射线

射线的机制相当于碰撞;

创建射线:

1 Ray ray=new Ray();

origin : 射线发射的原点;

direction: 射线发射的方向;

distance: 射线的长度;

hitInfo: 如果返回true,hitInfo将包含碰撞器碰撞的更多信息;

Layer: gameObject的层;

LayerMask: 只选定LayerMask层内的碰撞器,其他层内碰撞器忽略;返回bool类型,当射线与任何碰撞器碰撞时为真,反之为假;

射线碰撞的应用:

使用Physics类方法Raycast方法实现射线碰撞检测功能;

射线的添加方法:

1 bool Raycast(Ray ray,out RaycastHit hitInfo);       // Ray ray是要发射的射线, hitInfo是碰撞信息;
2 // 从主摄像头到鼠标点击位置创建一条射线;
3 Ray ray=Camera.main.ScreenPiontToRay(Input.mousePosition);

实际运用如代码所示:

 1 using Sysytem.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 public class RayScript:MonoBehaviour{
 5        public float speed;  // 外联速度值
 6
 7        Ray ray;  //   射线
 8        RaycastHit hit;   //   射线的碰撞信息
 9        LayerMask mask;   //   用来接收LayerMask的value值;
10 void Start(){
11         // 1<<10打开第10层,当前射线只能检测到第十层上的碰撞体;
12         // ~(1<<10)打开除10层以外的所有层;
13         //~(1<<0)打开所以层, 或者不写LayerMask;
14         // (1<<8)|(1<<10) 同时打开第8层和第10层;
15         mask = ~(1 << LayerMask.NameToLayer ("Cube"));
16     }
17  void Update(){
18        CubeMove();     //  调用CubeMove的方法
19
20        // 从自身位置发射射线;
21        // 发射一条射线,返回检测到的第一个物体;返回值为bool;
22        ray=new Ray(transform.position,transform.forward);
23        if(Physics.Raycast(ray,out hit,10)){
24        // 给射线添加颜色,只能在scene场景中显示,game场景中不会显示;
25        // 因为没有没有添加刚体,所以这里用collider来获取碰撞位置;
26        Debug.DrawLine(transform.position,hit.collider.transform.position,Color.red);  //碰撞物体中心的位置;
27  //    Debug.DrawLine(transform.position,hit.point,Color.red);       //  point是射线碰撞点的位置;
28
29         //  可以用Debug来调试看看 本方法是否运行;
30         Debug.Log("调试");
31          }
32          //
33          #region
34          //
35          //  得到射线范围内的所有游戏物体;
36          //返回的是一个游戏物体的数组;所以定义一个数组来接收得到的游戏物体;
37          RaycastHit[]  hits=Physics.RaycastAll(ray,10);      //  这里代入的参数为射线和射线的距离;
38          if(hits.Length>0){
39          // 打印,检查是否运行了次方法;
40
41          Debug.Log(hits.Length);
42           }
43          #endregion
44
45          //
46          #region
47          //
48         //  一般我们采用摄像头来发射线;
49        if (Input.GetMouseButtonDown(0)) {
50             //屏幕坐标转换成射线位置;
51             Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
52             if (Physics.Raycast (ray, out hit)) {
53                 //   缓动  Lerp
54                 transform.position = Vector3.Lerp (transform.position, hit.point, Time.deltaTime);
55             }
56         }
57          Ray ray2 = new Ray (transform.position, transform.forward);
58         //   通过LayerMask.NameToLayer方法 来找寻 层名为 "Cube"的层数,打开第N值,射线只能检查到这一层;
59         LayerMask mask = 1 << (LayerMask.NameToLayer ("Cube"));
60         if (Physics.Raycast (ray2, out hit, 100,mask.value)) {
61             Debug.Log (hit.collider.gameObject.name);
62         }
63          #endregion
64        }
65   void CubeMove(){
66         float hor = Input.GetAxis ("Horizontal");
67         float ver = Input.GetAxis ("Vertical");
68 //        transform.position += transform.forward * Time.deltaTime * ver * speed;
69 //        transform.position += transform.right * Time.deltaTime * hor * speed;
70         // 恒等于
71         transform.position += (transform.forward * ver + transform.right * hor) * speed * Time.deltaTime;
72 }

在Unity中每个GameObject都有Layer属性,  Layer一共有32层,0-7层,默认不可以编译,并且不能增加层数;

GameObject的Layers(层):

Layers通常用来被摄像机用来渲染部分场景,和灯光照射部分场景使用, 可以用来做射线检测时忽略一些collider或者CCollision时使用;

编辑Layers:

如果Layers处于开启状态那么就能通过Layers找寻到GameObject;

开启方法:

1 LayerMask mask=1<< 你需要开启的Layers层;

如果Layers处于关闭状态那么就可以在进行射线检测的时候忽略掉;

关闭方法:

1 LayerMask mask=0<<你需要关闭的Layers层;
2 或者
3 LayerMask mask=~(1<<你需要开启的Layers层);     //   ~表示取反

例如:

1 LayerMask mask = 1 << 2; 表示开启Layer2;
2 LayerMask mask = 0 << 5;表示关闭Layer5;    //  恒等于 LayerMask mask=~(1<<5);
3 LayerMask mask = 1<<2|1<<8;表示开启Layer2和Layer8;
4 LayerMask mask = 0<<3|0<<7;表示关闭Layer3和Layer7;   // 恒等于 LayerMask mask=~(1<<7);

实战:

场景中创建N(两个以上)个物体,鼠标可以选中任何物体,当鼠标选中为非地面时,选中的物体变为红色,之前选中的物体恢复为之前的颜色,鼠标点击到地面时,让之前选中的那个物体移动的当前点击的位置;

分析: 在场景中创建一块地板,几个游戏物体,这样采用摄像头发射射线

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4
 5 public class GameScript : MonoBehaviour {
 6
 7     private GameObject selectedGameObject;  // 用来记录点中的物体
 8     private bool flag; // 标记当前是否选中了地面
 9     private Color seletedColor; // 记录当前选中物体的颜色;
10     private RaycastHit hit;   // 碰撞信息;
11
12     void Update () {
13
14
15         if (Input.GetMouseButtonDown (0)) {
16             // 从摄像头发射一条经过鼠标点击屏幕的点的射线,如果射线碰撞到碰撞体该方法返回true,否则false;
17             if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit)) {
18                 // 判断鼠标是否点击到地面
19                 if (hit.collider.name == "Plane") {
20                     flag = true;
21
22                 } else {
23
24                     flag = false;
25
26                     // 判断是否选中物体
27                     if (selectedGameObject) {
28
29                         //  将前一个旋转的物体颜色恢复为原来的颜色;
30                         selectedGameObject.GetComponent<MeshRenderer> ().material.color = seletedColor;
31                     }
32                     // 更新选中的物体;
33                     selectedGameObject = hit.collider.gameObject;
34                     seletedColor = selectedGameObject.GetComponent<MeshRenderer> ().material.color;
35
36                     selectedGameObject.GetComponent<MeshRenderer> ().material.color = Color.red;
37                 }
38             }
39
40         }
41             if (flag && selectedGameObject) {   // 当这一次鼠标选择地面,并且被选中物体存在;
42
43                 Move (hit.point);
44             }
45     }
46
47
48     void Move(Vector3 distination){
49         // 判断两者之间的距离
50         if (Vector3.Distance(selectedGameObject.transform.position,distination) <= 0.01f) {
51
52             selectedGameObject.transform.position = distination;
53         } else {
54
55             // 不希望在Y轴上下移动
56
57             Vector3 pos = selectedGameObject.transform.position;  // 自身的位置;
58
59             pos = Vector3.Lerp (selectedGameObject.transform.position, distination, Time.deltaTime);
60
61             // 限制Y轴移动
62             selectedGameObject.transform.position = new Vector3 (pos.x, selectedGameObject.transform.position.y,
63             pos.z);
64
65         }
66     }
67 }
时间: 2024-10-19 21:03:37

Ray射线的相关文章

Unity3D 之射线检测

这里来记录下射线检测的相关内容: 射线检测故名就是通过射线去检测是否和碰撞器产生了交集,和碰撞器与碰撞器发生交集一样,会返回一个真. 射线的用法很多:比如检测是否跳跃,通过向地面投射射线控制在地面时候可以跳起. 射击游戏中可以通过定长射线去判断目标物体是否被击中,等 主要用到的工具类是: Physics RaycastHit 光线投射碰撞 Ray 射线 第一种是: Physics.Linecast 线性投射 从开始位置到结束位置做一个光线投射,如果与碰撞体交互,返回真. Debug.DrawLi

three.js 来源目光(十三)Math/Ray.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚開始学,好多地儿肯定不正确还请见谅. 下面代码是THREE.JS 源代码文件里Math/Ray.js文件的凝视. 很多其它更新在 : https://githu

射线,克隆,画线

1,射线 (1)Ray射线 A ray is an infinite line starting at origin and going in some direction. Ray是具有开始点和方向的无穷线. 构造: Ray ray = new Ray(transform.position, transform.forward); transform.position为起点, transform.forward为方向.(2)Raycast射线投射C# => public static bool

Unity 射线

射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 .用途:在unity中射线应用范围比较广, 多用于碰撞检测(如:子弹飞行是否击中目标).角色移动 等. 相关API: 1.Ray Camera.main.ScreenPointToRay(Vector3 pos)   返回一条射线Ray从摄像机到屏幕指定一个点 2.Ray Camera.main.ViewportPointToRay(Vector3 pos)  返回一条射线Ray从摄像机到

射线投射与碰撞层

射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 .用途:在unity中射线应用范围比较广, 多用于碰撞检测(如:子弹飞行是否击中目标).角色移动 等. 相关API: 1.Ray Camera.main.ScreenPointToRay(Vector3 pos)   返回一条射线Ray从摄像机到屏幕指定一个点 2.Ray Camera.main.ViewportPointToRay(Vector3 pos)  返回一条射线Ray从摄像机到

unity3d-射线(Ray)

射线Ray 射线是一个点向另外一个点发生的一条线,一旦与其他模型发生碰撞,他将停止发射.注意这条件是逻辑上的,界面上看不到. 一般使用射线判断是否发射至某个游戏对象上或者获得鼠标点击的游戏对象等. 用Camera.main.ScreenPointToRay向屏幕发射一条射线. 1 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 2 RaycastHit hit; 3 if(Physics.Raycast(ray,out h

three.js 源码注释(十三)Math/Ray.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚开始学,好多地儿肯定不对还请见谅. 以下代码是THREE.JS 源码文件中Math/Ray.js文件的注释. 更多更新在 : https://github.co

Unity获取摄像机在某个平面上的视野范围

这是已知平面上的一个点和平面的法线的情况下,求摄像机在平面看到的视野范围,下图绿色的框框就是了. 效果: 代码: 1 using UnityEngine; 2 using System.Collections; 3 using System; 4 5 public class CameraPlaneView : MonoBehaviour 6 { 7 #region for debug 8 public Camera viewCamera; 9 10 void Update() 11 { 12

Unity3D脚本学习——运行时类

AssetBundle 类,继承自Object.AssetBundles让你通过WWW类流式加载额外的资源并在运行时实例化它们.AssetBundles通过BuildPipeline.BuildAssetBundle创建. 参见:WWW.assetBundle ,Loading Resources at Runtime ,BuildPipeline.BuildPlayer function Start () { var www = new WWW ("http://myserver/myBund