zoukankan      html  css  js  c++  java
  • 关于Unity中红外线瞄准的效果实现

    今天做一个FPS游戏的时候,由于我做的是第三人称的射击,所以需要一个枪的红外线瞄准的效果。

    一开始我在枪上挂一个很细很长的聚光灯,瞄准远处物体的时候,看起来有点红外线的样子,但是靠近之后光线就变成一个手电筒的那种光,不是我想要的效果。

    后来我用粒子特效,虽然远处近处都是一条射线,但是效果很粗糙,不是那种细细的有穿透的感觉,而是像激光一样,而且感觉不断生成粒子,性能消耗会很大。

    最后在网上看到有人用Unity3.5自带的例子AngryBots里面有红外瞄准效果,但是代码有点问题,就改了一下,感觉效果还可以。

    红外线瞄准的效果实现:

    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节点挂在枪的指定位置作为子节点,运行的效果

  • 相关阅读:
    Atitit 人脸识别 眼睛形态 attilax总结
    Atitit 手机号码选号 规范 流程 attilax总结 v2 r99.docx
    atitit 板块分类 上市公司 龙头企业公司 列表 attilax总结.docx
    Atititi atiitt eam pam资产管理 购物表去年.xlsx
    使用cmd查看电脑连接过的wifi密码(一)
    常见十大web攻击手段 悟寰轩
    常见web攻击方式 悟寰轩
    【MYSQL数据库】MYSQL学习笔记mysql分区基本操作 悟寰轩
    Filter及FilterChain的使用详解 悟寰轩
    启动tomcat spring初始化两次问题(eg:@PostConstruct) 悟寰轩
  • 原文地址:https://www.cnblogs.com/HangZhe/p/7419978.html
Copyright © 2011-2022 走看看