- 最后登录
- 2022-3-29
- 注册时间
- 2012-11-19
- 阅读权限
- 70
- 积分
- 3738
- 纳金币
- 3
- 精华
- 0
|
pstatus"> 本帖最后由 艾西格亚 于 2013-4-23 16:35 编辑
最近在研究unity自带的demo “AngryBots”,把里面的红外瞄准分离出来做了个小demo。
其中主要用到了两个知识点,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.
以上两个知识点不做详细介绍,想详细了解的可以去查文档
下面还是以脚本加注释的方法介绍
pointerCtrl.cs- 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 //这个脚本的主要用处就是每帧发射射线,并获取碰撞信
息- 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放在指定位置,
到此,在场景中添加一些物体,运行,如果光线碰到物体就会出现一个小红点,否则就没有,哇哈哈,想要的效果就出来了
完整文件下载
ray.rar
(64.24 KB, 下载次数: 21)
|
|