force里面的射线检测

和下边代码一样,这个有注释:

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using wvr;
  5 
  6 public class Waver_Shexian : MonoBehaviour {
  7 
  8     public float pointerThikness = 0.02f;//宽度
  9     public float pointerLength = 1000f;//长度
 10     public Material pointerMaterial;//射线的材质球
 11     public Color pointerHitColor = new Color(0f,0.5f,0f,1f);//点击到物体时候的颜色为绿色
 12     public Color pointerMissColor = new Color(0.8f,0f,0f,1f);//移开物体时候的颜色为红色
 13 
 14     public GameObject pointerHolder;//射线的整体
 15     public GameObject pointer;//射线
 16     public GameObject pointerTip;//射线头部
 17     private Vector3 pointerTipScale = new Vector3(0.05f, 0.05f, 0.05f);//头部的大小
 18 
 19     public LayerMask layerToIgnore = Physics.IgnoreRaycastLayer; //定义层级别
 20 
 21     private Transform pointerContectTarget = null;//用来存放射线碰到的物体的位置
 22     private float pointerContecDistance = 0; //原来物体 的长度 (实际的长度)
 23     Vector3 destination;//头位置
 24     Transform detalHitItem = null;//碰到的物体的位置
 25     Vector3 detaHitpos = Vector3.zero;//碰到点的位置;
 26     float detaldisance = 0;//实际射线的长度
 27     Transform previousTarget = null;//先前碰到 的物体
 28 
 29     public WVR_DeviceType type;//获取手柄类型
 30 
 31     //每次调用激活材质球的颜色
 32     private void OnEnable()
 33     {
 34        var tmpMaterial= Resources.Load("green")as Material;
 35         if (pointerMaterial!=null)//如果材质球不为空
 36         {
 37             tmpMaterial = pointerMaterial; //就把射线的颜色赋值给材质球存放
 38         }
 39         pointerMaterial = new Material(tmpMaterial);//材质球为空的时候就创建一个新的材质球
 40         pointerMaterial.color = pointerMissColor;
 41         InitPointer();
 42     }
 43     //解决实例化出两条射线
 44     private void OnDisable()
 45     {
 46         if (pointerHolder!=null)
 47         {
 48             Destroy(pointerHolder);
 49         }
 50     }
 51     //实例化射线
 52     void InitPointer()
 53     {
 54         //父物体存放东西 本身是个空物体
 55         pointerHolder = new GameObject(string.Format("[{0}]WorldPointer_SimplePointer_Holder", gameObject.name));
 56         pointerHolder.transform.parent = transform;
 57         pointerHolder.transform.localPosition = Vector3.zero;
 58 
 59         //创建射线
 60         pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
 61         pointer.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_Pointer", gameObject.name);
 62         pointer.transform.parent = pointerHolder.transform;
 63         pointer.GetComponent<BoxCollider>().enabled = false; //关闭他们的Collider
 64 
 65         //创建射线的头部
 66         pointerTip = GameObject.CreatePrimitive(PrimitiveType.Sphere);
 67         pointerTip.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_PointerTip",gameObject.name);
 68         pointerTip.transform.parent = pointerHolder.transform;
 69         pointerTip.transform.localScale = pointerTipScale;//射线头部大小
 70         pointerTip.GetComponent<SphereCollider>().enabled = false;//关闭圆形的Collider
 71 
 72         SetPointerTransform(pointerLength, pointerThikness);
 73     }
 74     //对射线的长 宽的设置 把他们和手柄结合
 75     void SetPointerTransform(float setLength,float setTickness)
 76     {
 77         var beamPosition = setLength/ (2+0.0001f); //先是手柄所在的位置
 78         //线
 79         pointer.transform.localScale = new Vector3(setTickness, setTickness, setLength);
 80         pointer.transform.localPosition = new Vector3(0, 0, beamPosition);
 81 
 82         //
 83         pointerTip.transform.localPosition = new Vector3(0, 0, setLength);
 84 
 85         pointerHolder.transform.localRotation = Quaternion.identity; //父物体不需要旋转
 86     }
 87     private void Update()
 88     {
 89         if (pointer.gameObject.activeSelf)
 90         {
 91             Ray pointerRaycast = new Ray(transform.position, transform.forward);//创建射线
 92             RaycastHit pointerColliderWith;
 93             var rayHit = Physics.Raycast(pointerRaycast, out pointerColliderWith, pointerLength, ~layerToIgnore);
 94             var pointerBeamLength= GetPointerBeamLength(rayHit, pointerColliderWith);//???????????
 95             //结构体信息的传入
 96             SetPointerTransform(pointerBeamLength, pointerThikness);
 97             if (WaveVR_Controller.Input(type).GetPressDown(WVR_InputId.WVR_InputId_Alias1_Trigger))
 98             {
 99                 RayClickAreas args = new RayClickAreas();
100                 args.target = detalHitItem;//碰到物体的位置
101                 args.device = type;//手柄类型
102                 args.hitpos = detaHitpos;//碰到点的位置
103                 NotifyEvent(detalHitItem.gameObject, "OnRayTriggerClicked", args);
104             }
105             //射线移开的时候
106             if (previousTarget&&previousTarget!=detalHitItem)//先碰到的物体不等于碰到的物体位置
107             {
108                 RayPointerAres args = new RayPointerAres();
109                 args.device = type;
110                 args.distance = detaldisance;//实际射线的长度
111                 args.target = previousTarget;//先碰到的物体
112                 NotifyEvent(previousTarget.gameObject, "OnRayPointOut", args);
113                 previousTarget = null;//清空碰到的物体
114             }
115             //移动到新物体时
116             if (rayHit&&previousTarget!=detalHitItem)//老物体 不等于新物体 的时候
117             {
118                 RayPointerAres args = new RayPointerAres();
119                 args.device = type;
120                 args.distance = detaldisance;//实际射线的长度
121                 previousTarget = detalHitItem;//把新点击 的物体赋值给老物体
122                 args.target = previousTarget;
123                 NotifyEvent(previousTarget.gameObject, "OnRayPointerIn", args);
124             }
125             if (!rayHit)
126             {
127                 previousTarget = null;
128             }
129 
130         }
131     }
132     //当射线碰到物体,射线变短(长度不击穿)
133     float GetPointerBeamLength(bool hasRayHit,RaycastHit collideWith)//判断点击到了物体没有,点击到的物体
134     {
135         var actualLength = pointerLength;//存放原本最长的长度
136         //光束没有碰到或更新目标 
137         if (!hasRayHit||(pointerContectTarget&&pointerContectTarget!=collideWith.transform))
138         {
139             pointerContectTarget = null;
140             pointerContecDistance = 0;
141             destination = Vector3.zero;//头的位置
142             detalHitItem = null;//碰到物体的位置  
143             UpdatePointerMaterial(pointerMissColor);
144         }
145         //击中目标
146         if (hasRayHit)
147         {
148             pointerContecDistance = collideWith.distance;//实际的长度
149             pointerContectTarget = collideWith.transform;//碰撞的位置
150             destination = pointerTip.transform.position;//头位置
151             detalHitItem = collideWith.collider.transform;//碰到物体的位置
152             detaHitpos = collideWith.point;//碰撞点的位置
153             detaldisance = collideWith.distance;//实际射线长度
154             UpdatePointerMaterial(pointerHitColor);
155         }
156         if (hasRayHit&&pointerContecDistance<pointerLength)//当实际长度小于原本的长度
157         {
158             actualLength = pointerContecDistance;
159         }
160         return actualLength;
161     }
162     //跟新材质球 的颜色
163     void UpdatePointerMaterial(Color color)
164     {
165         pointerMaterial.color = color;
166         SetPointerMaterial();
167     }
168     //设置颜色
169     void SetPointerMaterial()
170     {
171         pointer.GetComponent<Renderer>().material = pointerMaterial;
172         pointerTip.GetComponent<Renderer>().material = pointerMaterial;
173     }
174     //打包发给碰撞的物体 按下圆盘
175     void NotifyEvent(GameObject go,string funcName,object obj)//碰到的物体,名字,结构体类型
176     {
177         if (go==null||!go.activeSelf)
178         {
179             return;
180         }
181         go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
182     }
183     //碰到物体的信息
184     public Transform GetHitTrans()
185     {
186         return detalHitItem;
187     }
188     public Vector3 GetHitPos()
189     {
190         return detaHitpos;
191     }
192  
193 }
射线的主代码
 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 using wvr;
 5 
 6 public struct RayClickAreas//射线碰撞到的物体信息
 7 {
 8     public WVR_DeviceType device;//类型
 9     public float padx, pady;//点击到的坐标
10     public Vector3 hitpos;//点击到的点
11     public Transform target;//点击到的物体;
12 }
13 public struct RayPointerAres//射线的信息
14 {
15     public WVR_DeviceType device;
16     public int flag;
17     public float distance;//距离
18     public Transform target;//点击到的物体
19 }
20 public class Waver_RayEvents : MonoBehaviour {
21 
22 
23 }
结构体

 

一。假射线的创建:

1.导入旧版本的SDK,
2.自己创建的脚本与WavVR里 的脚本名字一样,

3.绘制线的方式:

用Cube做一条线
4.射线的宽度和长度
5.放入OnEnable()里面。每次调用就被激活
6.。Resources专门放射线 的材质球
7.给射线赋值颜色:

 

8实例化.射线的整体:

 

//

8.射线的父物体,是一个空物体

//代码里面起名字
放在脚本的物体下边
位置

 

8.1 实例化射线是一个cube

 //创造出来

//改名字

//放的位置

8.2射线 的头部:

头部的大小:

 

总体 的样子,方法里的代码(创造出射线):

 

 9,设置一个新方法Transform(射线的长度宽度)

 9.1开始的时候:

9.2
//手柄在0.0.0的位置,Cube的位置是一半才是中心点
//射线大小

//射线的位置 z轴的方向

 

//射线放的位置(射线长度减去射线头部的半径)半径可以不用减去

 //父物体没有角度

解决实例化出两条射线的:

 

 

 效果:

 

 二、真的射线制作

1.检测射线是否存在
2.射线的起始坐标和方向
3.控制层级:射线不能检测到的层级  j纠正为:

 

4.除了这个层的,射线都可以检测:方法就是在层前面加一个波浪线~

 

 

5.定义一个新方法,当射线碰到物体,射线就变短:

 

5.1用来存放射线碰到的物体

5.2把 倒地碰着物体没有,

5.3原来物体射线的长度

5.4

//存原来照射目标的位置 

 j  解释

 

 

5.5拿到位置信息*(总的部分)
  

 

 

 代码汇总(假射线的创建,真射线的实现部分):

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 
  5 public class WaveVR_SimplePointer : MonoBehaviour {
  6 
  7     public float pointerThickness = 0.02f;//宽度
  8     public float pointerLength = 100f;//长度
  9     public Material pointerMaterial;
 10     public LayerMask layerToIgnore = Physics.IgnoreRaycastLayer;
 11 
 12     public Color pointerHitColor = new Color(0f,0.5f,0f,1f);//点击到物体的颜色
 13     public Color pointerMissColor = new Color(0.8f,0f,0f,1f);
 14 
 15     private GameObject pointerHolder;//射线的整体
 16     private GameObject pointer;//射线
 17     private GameObject pointerTip;//射线头部
 18     private Vector3 pointerTipScale = new Vector3(0.05f,0.05f,0.05f);
 19 
 20     private Transform pointerContectTarget = null;
 21     private float pointerContectDistance=0f;
 22     Vector3 destination;
 23     Transform detalHitItem = null;
 24     Vector3 detalHitpos = Vector3.zero;
 25     float detaldistance = 0f;
 26     Transform previousTarget = null;
 27 
 28 
 29     private void OnEnable()
 30     {
 31         var tmpMaterial=Resources.Load("WorldPointer") as Material;
 32         if (pointerMaterial != null)
 33         {
 34             tmpMaterial = pointerMaterial;
 35         }
 36         pointerMaterial = new Material(tmpMaterial);
 37         pointerMaterial.color = pointerMissColor;
 38         InitPointer();
 39     }
 40      void Update()
 41     {
 42         if (pointer.gameObject.activeSelf)
 43         {
 44             Ray pointerRaycast = new Ray(transform.position,transform.forward);
 45             RaycastHit pointerColliderWith;
 46             var rayHit= Physics.Raycast(pointerRaycast, out pointerColliderWith,~layerToIgnore);
 47             var pointerBeamLength= GetPointerBeamLength(rayHit, pointerColliderWith);
 48 
 49         }
 50     }
 51     void InitPointer()
 52     {
 53         pointerHolder = new GameObject(string.Format("[{0}]WorldPointer_SimplePointer_Holder", gameObject.name));
 54         pointerHolder.transform.parent = transform;
 55         pointerHolder.transform.localPosition = Vector3.zero;
 56 
 57         pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
 58         pointer.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_Pointer",gameObject.name);
 59         pointer.transform.parent = pointerHolder.transform;
 60         pointer.GetComponent<BoxCollider>().enabled = false;
 61 
 62         pointerTip = GameObject.CreatePrimitive(PrimitiveType.Sphere);
 63         pointerTip.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_PointerTip", gameObject.name);
 64         pointerTip.transform.parent = pointerHolder.transform;
 65         pointerTip.GetComponent<SphereCollider>().enabled = false;
 66         pointerTip.transform.localScale = pointerTipScale;
 67         SetPointerTransform(pointerLength,pointerThickness);
 68     }
 69     void SetPointerTransform(float setLength,float setTickness)
 70     {
 71         var beamPosition = setLength / (2 + 0.0001f);
 72         //线
 73         pointer.transform.localScale = new Vector3(setTickness,setTickness,setLength);
 74         pointer.transform.localPosition = new Vector3(0f, 0f, beamPosition);
 75         //
 76         pointerTip.transform.localPosition = new Vector3(0f,0f,setLength);
 77 
 78         pointerHolder.transform.localRotation = Quaternion.identity;
 79 
 80     }
 81      float GetPointerBeamLength(bool hasRayHit,RaycastHit collideWith)
 82     {
 83         var actualLength=pointerLength;
 84         //光束没有碰到物体或更新目标
 85         if (!hasRayHit||(pointerContectTarget&&pointerContectTarget!=collideWith.transform))
 86         {
 87             pointerContectTarget = null;
 88             pointerContectDistance = 0f;
 89             destination = Vector3.zero;
 90             detalHitItem = null;           
 91         }
 92         if (hasRayHit)
 93         {//击中目标
 94             pointerContectDistance=collideWith.distance;//实际距离
 95             pointerContectTarget = collideWith.transform;//碰撞位置
 96             destination=pointerTip.transform.position;//头位置
 97             detalHitItem=collideWith.collider.transform;//碰到物体的位置
 98             detalHitpos=collideWith.point;//碰撞点的位置
 99             detaldistance=collideWith.distance;//实际射线长度
100         }
101         if (hasRayHit&&pointerContectDistance<pointerLength)
102         {
103             actualLength = pointerContectDistance;
104         }
105 
106         return actualLength;
107     }
108 }

 三、更新材质球的颜色

四、设置颜色:

 

 

新脚本用来存信息:

结构体:
   

 

 

 

把结构体里的信息传入:

 

新方法 打包发给碰撞的物体:按下圆盘键

//碰到的物体,名字,结构体的类型

 

移走的时候:

移动到新物体:

 

 总的调用:

 

 碰到物体的信息:

点 的位置信息

 

 

 失活的时候,删除掉

 

 结构体脚本的代码:

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 using wvr;
 5 
 6 public struct RayClickAras//射线碰撞到的物体信息
 7 {
 8     public WVR_DeviceType device;
 9     public float padx, pady;
10     public Vector3 hitpos;
11     public Transform target;
12 }
13 public struct RayPointerAres//射线信息
14 {
15     public WVR_DeviceType device;
16     public int flag;
17     public float distance;
18     public Transform target;
19 }
20 public class WaveVR_RayEvent : MonoBehaviour {
21 
22     // Use this for initialization
23     void Start () {
24         
25     }
26     
27     // Update is called once per frame
28     void Update () {
29         
30     }
31 }

 

 主脚本的完整代码(对上边的补充):

 

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using wvr;
  5 
  6 public class WaveVR_SimplePointer : MonoBehaviour {
  7 
  8     public float pointerThickness = 0.02f;//宽度
  9     public float pointerLength = 100f;//长度
 10     public Material pointerMaterial;
 11     public LayerMask layerToIgnore = Physics.IgnoreRaycastLayer;
 12     public WVR_DeviceType type;
 13 
 14     public Color pointerHitColor = new Color(0f,0.5f,0f,1f);//点击到物体的颜色
 15     public Color pointerMissColor = new Color(0.8f,0f,0f,1f);
 16 
 17     private GameObject pointerHolder;//射线的整体
 18     private GameObject pointer;//射线
 19     private GameObject pointerTip;//射线头部
 20     private Vector3 pointerTipScale = new Vector3(0.05f,0.05f,0.05f);
 21 
 22     private Transform pointerContectTarget = null;
 23     private float pointerContectDistance=0f;
 24     Vector3 destination;
 25     Transform detalHitItem = null;
 26     Vector3 detalHitpos = Vector3.zero;
 27     float detaldistance = 0f;
 28     Transform previousTarget = null;
 29 
 30 
 31     private void OnEnable()
 32     {
 33         var tmpMaterial=Resources.Load("WorldPointer") as Material;
 34         if (pointerMaterial != null)
 35         {
 36             tmpMaterial = pointerMaterial;
 37         }
 38         pointerMaterial = new Material(tmpMaterial);
 39         pointerMaterial.color = pointerMissColor;
 40         InitPointer();
 41     }
 42     private void OnDisable()
 43     {
 44         if (pointerHolder!=null)
 45         {
 46             Destroy(pointerHolder);
 47         }
 48     }
 49     void Update()
 50     {
 51         if (pointer.gameObject.activeSelf)
 52         {
 53             Ray pointerRaycast = new Ray(transform.position,transform.forward);
 54             RaycastHit pointerColliderWith;
 55             var rayHit= Physics.Raycast(pointerRaycast, out pointerColliderWith,pointerLength,~layerToIgnore);
 56             var pointerBeamLength= GetPointerBeamLength(rayHit, pointerColliderWith);
 57             SetPointerTransform(pointerBeamLength,pointerThickness);
 58             if (WaveVR_Controller.Input(type).GetPressDown(WVR_InputId.WVR_InputId_Alias1_Bumper))
 59             {
 60                 RayClickAras args = new RayClickAras();
 61                 args.target = detalHitItem;
 62                 args.device = type;
 63                 args.hitpos = detalHitpos;
 64                 NotifyEvent(detalHitItem.gameObject,"OnRayTriggerClicked",args);
 65             }
 66             if (previousTarget&&previousTarget!= detalHitItem)
 67             {
 68                 RayPointerAres args = new RayPointerAres();
 69                 args.device = type;
 70                 args.distance = detaldistance;
 71                 args.target = previousTarget;
 72                 NotifyEvent(previousTarget.gameObject, "OnRayPointerOut", args);
 73                 previousTarget = null;
 74             }
 75             if (rayHit && previousTarget != detalHitItem)
 76             {
 77                 RayPointerAres args = new RayPointerAres();
 78                 args.device = type;
 79                 args.distance = detaldistance;
 80                 previousTarget = detalHitItem;
 81                 args.target = previousTarget;
 82                 NotifyEvent(previousTarget.gameObject,"OnRayPinterIn",args);
 83             }
 84             if (!rayHit)
 85             {
 86                 previousTarget = null;
 87             }
 88         }
 89     }
 90     void NotifyEvent(GameObject go,string funcName, object obj)
 91     {
 92         if (go==null||!go.activeSelf)
 93             return;
 94         go.SendMessage(funcName,obj,SendMessageOptions.DontRequireReceiver);
 95         
 96     }
 97     public Transform GetHitTrans()
 98     {
 99         return detalHitItem;
100     }
101     public Vector3 GetHitPos()
102     {
103         return detalHitpos;
104     }
105     void InitPointer()
106     {
107         pointerHolder = new GameObject(string.Format("[{0}]WorldPointer_SimplePointer_Holder", gameObject.name));
108         pointerHolder.transform.parent = transform;
109         pointerHolder.transform.localPosition = Vector3.zero;
110 
111         pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
112         pointer.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_Pointer",gameObject.name);
113         pointer.transform.parent = pointerHolder.transform;
114         pointer.GetComponent<BoxCollider>().enabled = false;
115 
116         pointerTip = GameObject.CreatePrimitive(PrimitiveType.Sphere);
117         pointerTip.transform.name = string.Format("[{0}]WorldPointer_SimplePointer_PointerTip", gameObject.name);
118         pointerTip.transform.parent = pointerHolder.transform;
119         pointerTip.GetComponent<SphereCollider>().enabled = false;
120         pointerTip.transform.localScale = pointerTipScale;
121         SetPointerTransform(pointerLength,pointerThickness);
122     }
123     void SetPointerTransform(float setLength,float setTickness)
124     {
125         var beamPosition = setLength / (2 + 0.0001f);
126         //线
127         pointer.transform.localScale = new Vector3(setTickness,setTickness,setLength);
128         pointer.transform.localPosition = new Vector3(0f, 0f, beamPosition);
129         //
130         pointerTip.transform.localPosition = new Vector3(0f,0f,setLength);
131 
132         pointerHolder.transform.localRotation = Quaternion.identity;
133 
134     }
135      float GetPointerBeamLength(bool hasRayHit,RaycastHit collideWith)
136     {
137         var actualLength=pointerLength;
138         //光束没有碰到物体或更新目标
139         if (!hasRayHit||(pointerContectTarget&&pointerContectTarget!=collideWith.transform))
140         {
141             pointerContectTarget = null;
142             pointerContectDistance = 0f;
143             destination = Vector3.zero;
144             detalHitItem = null;
145             UpdatePointerMaterial(pointerMissColor);
146 
147 
148         }
149         if (hasRayHit)
150         {//击中目标
151             pointerContectDistance=collideWith.distance;//实际距离
152             pointerContectTarget = collideWith.transform;//碰撞位置
153             destination=pointerTip.transform.position;//头位置
154             detalHitItem=collideWith.collider.transform;//碰到物体的位置
155             detalHitpos=collideWith.point;//碰撞点的位置
156             detaldistance=collideWith.distance;//实际射线长度
157             UpdatePointerMaterial(pointerHitColor);
158         }
159         if (hasRayHit&&pointerContectDistance<pointerLength)
160         {
161             actualLength = pointerContectDistance;
162         }
163 
164         return actualLength;
165     }
166     void SetPointerMetarial()
167     {
168         pointer.GetComponent<Renderer>().material = pointerMaterial;
169         pointerTip.GetComponent<Renderer>().material = pointerMaterial;
170     }
171     void UpdatePointerMaterial(Color color)
172     {
173         pointerMaterial.color = color;
174         SetPointerMetarial();
175     }
176 }

 

 错误纠正:

 

posted @ 2018-10-26 11:21  白纸菇凉  阅读(351)  评论(0编辑  收藏  举报