Unity实现红外线瞄准效果

发表于2018-11-23
评论0 7.1k浏览
在一些FPS游戏中,为了保证射击的准度,可能会加入红外线瞄准功能,本篇文章就是针对于此,给大家介绍红外线瞄准效果的实现,一起来看看吧。

红外线瞄准的效果实现:

1.创建一个空节点叫Laser,添加Line Renderer组件,里面关联一个材质,材质使用AngryBots里面的LaserMaterial.mat,材质纹理贴图是LaserTexture.psd和SimpleNoise.psd。Shader使用AngryBots里面的LaserScope.shader。这个是射线。

2.创建一个平面叫LaserDot作为Laser节点的子节点,Scale都设置为0.02,材质使用AngryBots里面的LaserDot.mat,材质纹理贴图是LaserDot.psd和SimpleNoise.psd。Shader使用AngryBots里面的LaserScope.shader。这个是射到物体表面时的一个红色的点。

3.创建一个脚本组件PreFrameRaycast挂载在Laser下面,用来发射一条射线,并返回射线的碰撞信息
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;
    }
}

4.创建一个脚本组件pointerCtrl挂载在Laser下面,用来绘制红外射线
打开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()
    {
        //光线看起来有动感
        GetComponent<Renderer>().material.mainTextureOffset += new Vector2(Time.deltaTime * aniDir * scrollSpeed, 0);
        //设置纹理偏移量
        GetComponent<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);
            GetComponent<Renderer>().material.mainTextureScale = new Vector2(0.1f * (hitInfo.distance), GetComponent<Renderer>().material.mainTextureScale.y);
            GetComponent<Renderer>().material.SetTextureScale("_NoiseTex", new Vector2(0.1f * hitInfo.distance * noiseSize, noiseSize));
            if (pointer)
            {
                pointer.GetComponent<Renderer>().enabled = true;
                //pointer.transform.position = hitInfo.point + (transform.position - hitInfo.point) * 0.01f;
                pointer.transform.position = hitInfo.point;
                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.GetComponent<Renderer>().enabled = false;
            }
            //光线的最大长度
            float maxDist = 200.0f;
            //当光线没有碰撞到物体,终点就是枪口前方最大距离处
            lRenderer.SetPosition(1, (this.transform.forward * maxDist));
            GetComponent<Renderer>().material.mainTextureScale = new Vector2(0.1f * maxDist, GetComponent<Renderer>().material.mainTextureScale.y);
            GetComponent<Renderer>().material.SetTextureScale("_NoiseTex", new Vector2(0.1f * maxDist * noiseSize, noiseSize));
        }
    }
}

5.把这个Laser节点挂在枪的指定位置作为子节点,运行效果如下:

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: