其中主要用到了两个知识点,RaycastHit和LineRenderer。从枪口处发射射线,然后根据射线的起点和碰撞点设置LineRenderer的起点和碰撞点设置那条线来模拟红外线瞄准。
1、hitInfo = new RaycastHit();
Physics.Raycast(tr.position,tr.forward,out hitInfo);
返回射线的碰撞信息
2、function SetPosition(int index,Vector3 position)
设置线的位置,这里只要控制两个点就可以了,起点index为0,终点1.
以上两个知识点不做详细介绍,想详细了解的可以去查文档
图片:未命名.jpg
下面还是以脚本加注释的方法介绍
pointerCtrl.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| using UnityEngine;
using System.Collections;
//转载请说明出处
public class pointerCtrl : MonoBehaviour
{
public float scrollSpeed = 0.5f;
public float pulseSpeed = 1.5f;
public float noiseSize = 1.0f;
public float maxWidth = 0.5f;
public float minWidth = 0.5f;
private float aniTime = 0.0f;
private float aniDir = 1.0f;
private LineRenderer lRenderer;
public GameObject pointer = null; //小红点
private PreFrameRaycast raycast; //光线投射
void Start ()
{
lRenderer = gameObject.GetComponent (typeof(LineRenderer)) as LineRenderer;
raycast = gameObject.GetComponent (typeof(PreFrameRaycast)) as PreFrameRaycast// Update is called once per frame
}
void Update ()
{
//光线看起来有动感
renderer.material.mainTextureOffset += new Vector2 (Time.deltaTime * aniDir * scrollSpeed, 0);
//设置纹理偏移量
renderer.material.SetTextureOffset ("_NoiseTex", new Vector2 (-Time.time * aniDir * scrollSpeed, 0.0f));
float aniFactor = Mathf.PingPong (Time.time * pulseSpeed, 1.0f);
aniFactor = Mathf.Max (minWidth, aniFactor) * maxWidth;
//设置光线的宽
lRenderer.SetWidth (aniFactor, aniFactor);
//光线的起点,枪口的地方
lRenderer.SetPosition(0,this.gameObject.transform.position);
if (raycast == null) {
Debug.Log ("raycast is null");
return;
}
//获取光线的碰撞信息
RaycastHit hitInfo = raycast.GetHitInfo ();
//光线碰撞到物体
if (hitInfo.transform) {
//光线的终点,即光线的碰撞点
lRenderer.SetPosition (1, hitInfo.point);
renderer.material.mainTextureScale = new Vector2 (0.1f * (hitInfo.distance), renderer.material.mainTextureScale.y);
renderer.material.SetTextureScale ("_NoiseTex", new Vector2 (0.1f * hitInfo.distance * noiseSize, noiseSize));
if (pointer) {
pointer.renderer.enabled = true;
pointer.transform.position = hitInfo.point + (transform.position - hitInfo.point) * 0.01f;
pointer.transform.rotation = Quaternion.LookRotation (hitInfo.normal, transform.up);
pointer.transform.eulerAngles = new Vector3 (90, pointer.transform.eulerAngles.y, pointer.transform.eulerAngles.z);
}
} else { //光线没有碰撞到物体
if (pointer) {
pointer.renderer.enabled = false;
}
//光线的最大长度
float maxDist = 200.0f;
//当光线没有碰撞到物体,终点就是枪口前方最大距离处
lRenderer.SetPosition (1, (this.transform.forward * maxDist));
renderer.material.mainTextureScale = new Vector2 (0.1f * maxDist, renderer.material.mainTextureScale.y);
renderer.material.SetTextureScale ("_NoiseTex", new Vector2 (0.1f * maxDist * noiseSize, noiseSize));
}
}
}
|
PreFrameRaycast.cs //这个脚本的主要用处就是每帧发射射线,并获取碰撞信
息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| using UnityEngine;
using System.Collections;
//转载请说明出处
public class PreFrameRaycast : MonoBehaviour {
private RaycastHit hitInfo;
private Transform tr;
// Use this for initialization
void Start () {
}
void Awake(){
tr = this.transform;
}
// Update is called once per frame
void Update () {
hitInfo = new RaycastHit();
Physics.Raycast(tr.position,tr.forward,out hitInfo);
Debug.DrawRay(tr.position,tr.forward,Color.red);
}
//返回射线的碰撞信息
public RaycastHit GetHitInfo(){
if(hitInfo.Equals(null)){
Debug.LogWarning("hitInfo is null");
}
return hitInfo;
}
}
|
创建一个空物体,然后把上边的两个脚本挂上去,还需要AngryBots里面的shader文件,给这个空物体加上Line Renderer组件,创建一个material,使用前面说道的shader文件,然后把texture拖到指定的位置,
在创建一个片面,命名为“LaserDot”这个就是光线碰到物体后的小红点,同样需要上面的shader,同样新建一个material放在指定位置,
到此,在场景中添加一些物体,运行,如果光线碰到物体就会出现一个小红点,否则就没有,哇哈哈,想要的效果就出来了
|
|
|
|
|
|