【unity小技巧】使用三种方式实现瞄准瞄具放大变焦效果

最终效果对比

在这里插入图片描述

文章目录

  • 最终效果对比
  • 前言
  • 第一种办法
  • 方法二
    • 1. 创建URP环境
    • 2. 配置 Universal Render Pipeline Asset
    • 3. 这里向我们新建一个无光的ShaderGraph
    • 4. 主图配置
    • 4. 新建材质,挂载
    • 5. 下面是shaderGraph 的连线图
    • 6. 新增脚本控制ObjectScreenPosition随着瞄准镜移动而不断修改
    • 6. 新增脚本控制_ZoomAmount实现滚轮放大缩小效果
  • 第三种办法
    • 1. 新增渲染相机
    • 2. 创建一个渲染纹理
    • 3. 绑定渲染纹理
    • 4. 解决镜片穿模问题
    • 5. 脚本控制实现放大缩小效果
  • 总结
  • 参考
  • 完结

前言

在许多射击类游戏中,瞄具的放大变焦效果是提高射击精准度和游戏体验的重要部分。Unity作为一款流行的游戏开发引擎,提供了多种实现瞄准瞄具放大变焦效果的方法。本文将介绍三种常见的实现方式,并分别探讨它们的优缺点。

首先,我们将介绍如何通过调整摄像机的视野来实现放大变焦效果。其次,我们将讨论如何利用Shader来实现瞄具的放大效果,以及如何使用Render Texture来模拟变焦效果。每种方法都有其独特的应用场景和适用性,在本文中,我们将深入探讨这三种方法的具体实现和使用场景,帮助开发者根据自身需求选择合适的实现方式。

无论您是初学者还是有经验的开发者,本文都将为您提供全面的教程和示例代码,帮助您更好地理解和运用Unity中的瞄具放大变焦效果。让我们开始探索这些令人兴奋的技术吧!

第一种办法

调节相机FOV值

public class RifleScopeZoom : MonoBehaviour
{
    [SerializeField] private Camera playerCamera;
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float minFOV = 20f;
    [SerializeField] private float maxFOV = 60f;

    private void Update()
    {
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        
        // 根据滚轮滑动的值调整 FOV
        playerCamera.fieldOfView -= scrollValue * zoomSpeed;
        
        // 限制 FOV 的范围在最小值和最大值之间
        playerCamera.fieldOfView = Mathf.Clamp(playerCamera.fieldOfView, minFOV, maxFOV);
    }
}

效果
在这里插入图片描述
这就是第一个实现方式,如你所见十分简单,它所作的就是调整主摄像机参数,这个方式的优点就是性能好,你不需要什么新Shader或者另一个相机,而只需要调整相机FOV,不过缺点就是不太好看,在理想情况下我们只会希望放大瞄准镜所看到的物体,不过现在整个画面都放大了

还有就是如果你的瞄准镜模型不是空心通透的可能无法使用这种方法,比如狙击枪的瞄准镜,我下面的例子就是,使用我只能去掉瞄准镜
在这里插入图片描述

方法二

对于第二个方法我们会需要用到Shader来放大某个物体背后的画面

1. 创建URP环境

如果不懂的可以看我之前的文章,有教具体如何配置URP环境:使用Shader Graph实现动物森友会的世界弯曲效果

2. 配置 Universal Render Pipeline Asset

由于实验中使用了 Scene Depth 和 Scene Color 节点获取深度缓冲区和颜色缓冲区信息,需要在 Universal Render Pipeline Asset 中勾选 Depth Texture 和 Opaque Texture,如下。
在这里插入图片描述

3. 这里向我们新建一个无光的ShaderGraph

在这里插入图片描述

4. 主图配置

由于镜子是透明的,需要在主图的 Graph Settings 中将 Surface Type 属性设置 Transparent
在这里插入图片描述

4. 新建材质,挂载

为了实现这个效果我在瞄准镜中放了个球,然后把它弄得很平,模拟一个镜面效果,绑定带前面ShaderGraph的材质
在这里插入图片描述

5. 下面是shaderGraph 的连线图

在这里插入图片描述
这里用了Scene Color节点它输出这个物体背后的场景颜色,然后用Tilling and offset节点修改其中的Tilling值来实现放大,然后就是用到物体屏幕坐标这个是最复杂的点ObjectScreenPosition,这个参数需要随着瞄准镜移动而不断修改。

6. 新增脚本控制ObjectScreenPosition随着瞄准镜移动而不断修改

因此我这里有另一个脚本RifleScopeShaderScreenPos,它的作用就是将物体世界坐标转屏幕坐标然后输入到Shader中,所以这个Shader不会放大所有画面,他只会放大瞄准镜里的东西

public class RifleScopeShaderScreenPos : MonoBehaviour
{
    // Shader 材质
    [SerializeField] private Material material;

    private void Update()
    {
        // 获取物体在屏幕上的像素坐标
        Vector2 screenPixels = Camera.main.WorldToScreenPoint(transform.position);
        // 将像素坐标转换为 0-1 的范围
        screenPixels = new Vector2(screenPixels.x / Screen.width, screenPixels.y / Screen.height);
        // 将物体的屏幕坐标传递给 Shader
        material.SetVector("_ObjectScreenPosition", screenPixels);
    }
}

6. 新增脚本控制_ZoomAmount实现滚轮放大缩小效果

public class RifleScopeZoomMaterial : MonoBehaviour
{
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float min  = 0f;
    [SerializeField] private float max = 1f;
    [SerializeField] private Material zoomMaterial;

    private void Update()
    {
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        scrollValue = zoomMaterial.GetFloat("_ZoomAmount") + scrollValue;

        // 限制的范围在最小值和最大值之间
        scrollValue = Mathf.Clamp(scrollValue, min, max);
        
        zoomMaterial.SetFloat("_ZoomAmount", scrollValue);
    }
}

在这里插入图片描述
和上一个方法相比优点就是它只放大瞄具所看到的东西,所以瞄具外的东西都不会变化,另一个优点就是相比于接下来的方法,这个方法不太吃性能,它只有一个Shader而且相机只渲染一次,当然也有缺点,有一个潜在的问题就是当你放大后画面会变成这样
在这里插入图片描述
当你放大倍率不是很高时画面凑合的过去,不过当你放的越大你就越会得到马赛克画面,这和画面的分辨率有关,Shader只是简单的放大了这个图片而不会改变它的分辨率,所以放的越大画面马赛克就会变明显,如果你放大的倍数不会太大这是个不错的方法,还有和前面有相同的问题,就是如果你的瞄准镜模型不是空心通透的可能不适合这种方法

第三种办法

我们得用一下渲染纹理特性,本质上来说就是可以把相机的画面渲染到一个纹理上

1. 新增渲染相机

所以我们需要一个新的相机,然后把它往前面拖一下,现在你可以把它拖到瞄准镜前面或者直接放在枪管上,然后通过拉低FOV来放大画面
在这里插入图片描述

2. 创建一个渲染纹理

我们再创建一个渲染纹理,这边主要设置一下尺寸,这主要取决于玩家分辨率以及瞄准镜在屏幕上的大小,这里1024*1024差不多够了

在这里插入图片描述
这样子我们就设置好了接下来让相机把渲染画面输出到这个纹理上
在这里插入图片描述
这样我门就能看到相机的画面己经渲染到这张纹理之中了
在这里插入图片描述

3. 绑定渲染纹理

接下来为了在瞄准镜中显示画面,我们直接在瞄准镜里边放一个Quad,我们只需要把渲染纹理拖进来就能得到瞄具画面了
在这里插入图片描述
这样就有效果了,下面就是放大后的相机画面了
在这里插入图片描述

4. 解决镜片穿模问题

不过还是有个小小的问题,那就是我门的Quad是方形的而瞄准镜是圆形的,所以你会看到它有些穿模了
在这里插入图片描述
一个很简单的解决办法就是只需要做一个透明度裁剪
在这里插入图片描述
这里也有个透明度裁剪预制,只需要确保你到设置面板理启出Alpha clip
在这里插入图片描述
做完之后点击这边的AlphaClipMask选择一张带透明背景的圆形贴图
在这里插入图片描述
完了之后你会看到遮罩外边的贴图被裁减了它只保留了中间的画面
在这里插入图片描述

5. 脚本控制实现放大缩小效果

最后一步就是要处理脚本了,我们要做的就是调整渲染纹理相机的FOV,可以复用前面的代码,不够记得把相机修改为我们的渲染相机,而不是主相机

public class RifleScopeZoom : MonoBehaviour
{
    [SerializeField] private Camera playerCamera;
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float minFOV = 20f;
    [SerializeField] private float maxFOV = 60f;

    private void Update()
    {
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        
        // 根据滚轮滑动的值调整 FOV
        playerCamera.fieldOfView -= scrollValue * zoomSpeed;
        
        // 限制 FOV 的范围在最小值和最大值之间
        playerCamera.fieldOfView = Mathf.Clamp(playerCamera.fieldOfView, minFOV, maxFOV);
    }
}

效果
在这里插入图片描述
我可以放大我想要的地方,如你所见和上一个方法相比没有马赛克问题,而且这个方法有一个有趣的特性,那就是即使我枪没有抬起来时瞄具上的画面也在变化
在这里插入图片描述
另一个优点就是由于我使用了另一个相机,因此我可以做一些有趣的东西,比如我可以用不同的后处理效果,我可以在主相机上加上景深效果,由于渲染纹理离相机很近所以它没被模糊化而外边的东西都模糊掉了
在这里插入图片描述

在这里插入图片描述
就个人而言这个观感效果最好,瞄具外的画面被模糊掉了但内部的画面仍然很清楚,如果你想的话你可以把镜子往前放一放来用其他的后处理效果,你可以实现镜内热成像或者夜视效果而镜外画面保持正常。

当然了这个方法也有一个大缺点那就是性能问题,这个方式使用渲染纹理来显示第二个相机的画面,本质上画面被渲染了2次,如果你做的游戏是PC端这可能不会是个大问题,而如果是手游的话可能就是大问题了,如果你可以承受性能代价,这个方法是最好的一个。

总结

好了你已经学完这三个瞄准镜放大方法了,第一个方法适合性能优先需求或者想找最简单实现方式的人,第二个方法稍优于第一
而最后一个你会得到最好的瞄具效果,去选一个适合的方法用在你的项目里吧!
在这里插入图片描述

参考

【视频】https://www.youtube.com/watch?v=9g2VqJvWnQI

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/257344.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

org.slf4j日志组件实现日志功能

slf4j 全称是Simple Logging Facade for Java。facade是一种设计模式。 slf4j 是一个抽象程度更高的日志组件,本身并不提供实际的日志功能。实际的日志功能是通过log4j等日志组件实现,而使用者只需要关心 slf4j 给出的API。 slf4j 仅仅是一个为Java程序提…

bootstap table表格, 获取当前点击的table元素在该行是第几个

背景 有这样一个需求, table表格中是统计数据, 要求点击每个单元格可实现导出统计的底层数据 数据都是可点击导出的, 思路 获取行bootstap 有个index参数, 所哟要获取当前行第几列, 要获取当前点击的table元素在其所在行中的位置(即第几个)&#xff…

《每天一分钟学习C语言·二》

1、当使用const关键字变量就无法修改可当常量来用。常量指针不能通过指针来改变变量的值,但可以通过其他引用来改变变量的值常量指针也可以指向其他变量地址,如 int a5,b6; const int *pt &a; *pt6; //错误 a6; //正确 pt&b; //正确指针常量指…

0057-基本数据类型和 String 类型的转换

文章目录 基本数据类型和 String 类型的转换注意事项 基本数据类型和 String 类型的转换 注意事项

Oracle的学习心得和知识总结(三十)| OLTP 应用程序的合成工作负载生成器Lauca论文翻译及学习

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《Oracle Database SQL Language Reference》 2、参考书籍:《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

计算机网络:物理层(编码与调制)

今天又学会了一个知识,加油! 目录 一、基带信号与宽带信号 1、基带信号 2、宽带信号 3、选择 4、关系 二、数字数据编码为数字信号 1、非归零编码【NRZ】 2、曼彻斯特编码 3、差分曼彻斯特编码 4、归零编码【RZ】 5、反向不归零编码【NRZI】 …

.NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证

public Task InvokeAsync(HttpContext context){// 获取终点路由特性var endpointFeature context.Features.Get<IEndpointFeature>();// 获取是否定义了特性var attribute endpointFeature?.Endpoint?.Metadata?.GetMetadata<AllowAnonymousAttribute>();if …

giee 添加公匙 流程记录

一、安装 百度网盘CSDN4文件夹下&#xff0c;或者官网下载&#xff1a;https://git-scm.com/downloads 二、生成密钥 1.右击打开git bash 2.$ ssh-keygen -t rsa -C “个人邮箱地址”&#xff0c;按3个回车&#xff0c;密码为空。 3.在C:\Users{windows用户名}.ssh目录下得到…

G1506 小电流升压型LED驱动芯片

G1506 小电流升压型LED驱动芯片 概述 &#xff1a; G1506是一种专为以恒定电流来驱动白光LED而设计的升压型DC/DC变换器。该器件能利用一节锂离子电池来驱动两个、三个或四个串联的LED采用LED串联连接的方法可以提供相等的LED电流从而能获得均匀的亮度且无需镇流电阻器。G1506的…

查找Apple Watch的序列号有重要意思,主要有两种方法

如果你打算购买二手Apple Watch&#xff0c;你可能需要检查它的序列号或IMEI号&#xff0c;来确保可靠性。以下是如何从Apple Watch和iPhone中查找序列号。 在Apple Watch上查找序列号和IMEI 1、在Apple Watch上&#xff0c;按下手表表面的数字皇冠以打开应用程序网格或列表。…

Unity中Shader测试常用的UGUI功能简介

文章目录 前言一、锚点1、锚点快捷修改位置2、使用Anchor Presets快捷修改3、Anchor Presets界面按下 Shift 可以快捷修改锚点和中心点位置4、Anchor Presets界面按下 Alt 可以快捷修改锚点位置、UI对象位置 和 长宽大小 二、Canvas画布1、UGUI中 Transform 变成了 Rect Transf…

华清远见嵌入式学习——ARM——作业1

要求&#xff1a; 代码&#xff1a; mov r0,#0 用于加mov r1,#1 初始值mov r2,#101 终止值loop: cmp r1,r2addne r0,r0,r1addne r1,r1,#1bne loop 效果&#xff1a;

Python 全栈体系【四阶】(七)

第四章 机器学习 六、多项式回归 1. 什么是多项式回归 线性回归适用于数据呈线性分布的回归问题。如果数据样本呈明显非线性分布&#xff0c;线性回归模型就不再适用&#xff08;下图左&#xff09;&#xff0c;而采用多项式回归可能更好&#xff08;下图右&#xff09;。例…

【开源软件】最好的开源软件-2023-第六名 Solid

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

ac转dc电源芯片SM7025 支持12V/18V输出电压

AC转DC电源芯片是一种能够将交流电转换为直流电的重要器件&#xff0c;广泛应用于电子设备和电源系统中。它可以提供稳定的直流电源&#xff0c;为设备的正常运行提供保障。 AC转DC电源芯片的工作原理是利用内部的整流、滤波、变压器和稳压等电路&#xff0c;将输入的交流电转换…

深耕元宇宙领域,强势发力文旅市场

2023年12月14日&#xff0c;“承上启下 智元宇宙&#xff1a;2024元宇宙与人工智能应用场景闭门会——苏州”在苏州泰山路2号百度VR&#xff08;苏州&#xff09;赋能中心成功举办。会议邀请了苏州本地的相关优秀企业代表、科创精英、投资与行业技术代表、公司创始人共计约50余…

MyBatis持久层框架

四、MyBatis持久层框架 目录 一、Mybatis简介 1. 简介2. 持久层框架对比3. 快速入门&#xff08;基于Mybatis3方式&#xff09; 二、日志框架扩展 1. 用日志打印替代sout2. Java日志体系演变3. 最佳拍档用法4. Lombok插件的使用 4.1 Lombok简介4.2 Lombok安装4.3 Lombok使用注…

关于“Python”的核心知识点整理大全29

目录 11.2.4 方法 setUp() 注意 11.3 小结 第二部分 项目1 外星人入侵 第&#xff11;2 章 武装飞船 注意 12.1 规划项目 12.2 安装 Pygame 注意 12.2.1 使用 pip 安装 Python 包 注意 如果你启动终端会话时使用的是命令python3&#xff0c;那么在这里应使用命令…

人工智能超分辨率重建:揭秘图像的高清奇迹

导言 人工智能超分辨率重建技术&#xff0c;作为图像处理领域的一项重要创新&#xff0c;旨在通过智能算法提升图像的分辨率&#xff0c;带来更为清晰和细致的视觉体验。本文将深入研究人工智能在超分辨率重建方面的原理、应用以及技术挑战。 1. 超分辨率重建的基本原理 …

Human Perception of Visual Information (1)

There is one thing the photograph must contain, the humanity of the moment. —Robert Frank 照片必须包含一件事&#xff0c;那就是这一刻的人性。 罗伯特。弗兰克 perface 利用机器学习和大规模数据收集的最新成果&#xff0c;客观视觉属性(如语义内容和几何关系)的计算…