关于Unity中红外线瞄准的效果实现
实现 关于 效果 Unity 瞄准
2023-09-11 14:21:18 时间
今天做一个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节点挂在枪的指定位置作为子节点,运行的效果
相关文章
- 关于python中矩阵的实现和矩阵的转置
- C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
- C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路
- 关于STM32的I2C硬件DMA实现
- HashSet实现原理是什么?有什么特点?
- 怎么实现动态代理?
- 银行借“大数据”实现POS“秒贷”
- 关于输入提示功能实现前的基本参考
- 关于popupwindow的两种实现方式
- NLog 在NetCore中实现多实例注入DI, 实现多租户模式
- MFC VC 双缓冲绘图基本原理与实现,详细解释
- 基于C+++FLTK实现(WinForm)超市收银系统【100010032】
- 关于sentinel LDK加密war包实现应用加密的使用方法
- java中关于SSL/TSL的介绍和如何实现SSL Socket双向认证
- 关于Android配色 自适应颜色的实现
- Android 使用加速度传感器实现摇一摇功能及优化
- android 开发 实现自动安装
- 浅析如何利用逐帧动画配合补间动画实现一个无限循环的文字及图片轮播效果
- Android学习之关于实现子线程需要掌握的两种方式
- Unity 进阶 之 简单虚拟摇杆joystick的实现,并对应简单控制物体移动和旋转的整理(简单适配到Vuforia 识别放置场景使用)
- Unity 使用JSON实现本地数据保存和读取
- SpringBoot+Vue实现的在线点餐系统 附带详细运行指导视频
- STM32-CAN配置与库函数解析,实现环回模式通信