【Unity高级】如何动态调整物体透明度

本文介绍了如何设置及动态调整物体的透明度。

一、手动设置的方法

我们先来看下如何手动设置物体的透明度。

物体的透明与否是通过材质来设置的。只有我们把具有透明度的材质指给物体的渲染器(Render),物体就被设置成相应的透明度了。

看一下上面半透明(左二)物体的材质设置。

(1)将材质的Surface Type设置为Transparent,Blending Mode设置为Alpha。

(2)点开Base Map,(3)调整A值(Alpha通道)来改变透明度

(4)也可以调整物体表面光滑度,调整材质效果(比如玻璃)。

二、使用代码设置

如果我们想在运行时动态调整物体的透明度的话,可以通过设置材质的相关参数来实现。

两个核心方法如下:

1. SetMaterialOpaque() - 设置材质为不透明

当透明度值大于或等于 1 时,调用此方法将材质设置为不透明。

    private void SetMaterialOpaque(){targetMaterial.SetFloat("_Surface", 0); // 设置材质为不透明,0 = OpaquetargetMaterial.SetOverrideTag("RenderType", "Opaque"); // 设置渲染类型标签为不透明targetMaterial.SetInt("_Blend", 0); // 设置混合模式为不透明targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); // 设置源混合模式为 OnetargetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // 设置目标混合模式为 ZerotargetMaterial.SetInt("_ZWrite", 1); // 启用深度缓冲区写入(不透明物体需要写入深度缓冲区)targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry; // 设置渲染队列为几何体渲染队列(不透明物体)targetMaterial.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); // 禁用透明表面类型关键字Color color = targetMaterial.GetColor("_BaseColor"); // 获取材质的基础颜色color.a = 1f; // 设置透明度为 1,完全不透明targetMaterial.SetColor("_BaseColor", color); // 更新材质的颜色}
  • 设置材质属性
    • targetMaterial.SetFloat("_Surface", 0):将材质的 _Surface 属性设置为 0,表示材质为不透明(Opaque)。

    • targetMaterial.SetOverrideTag("RenderType", "Opaque"):设置渲染类型标签为不透明。

    • targetMaterial.SetInt("_Blend", 0)targetMaterial.SetInt("_SrcBlend", 1)targetMaterial.SetInt("_DstBlend", 0):这些设置指定了混合模式为不透明(没有透明度混合)。

    • targetMaterial.SetInt("_ZWrite", 1):启用 Z 缓冲区写入(不透明物体需要写入深度缓冲区)。

    • targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry:设置渲染队列为几何体渲染队列(不透明物体通常在此队列中渲染)。

    • Color color = targetMaterial.GetColor("_BaseColor"); color.a = 1f; targetMaterial.SetColor("_BaseColor", color);:设置材质的颜色透明度为 1,表示完全不透明。

2. SetMaterialTransparent(float alpha) - 设置材质为透明

当透明度值小于 1 时,调用此方法将材质设置为透明,并根据透明度值调整材质的透明度。

 private void SetMaterialTransparent(float alpha){targetMaterial.SetFloat("_Surface", 1); // 设置材质为透明,1 = TransparenttargetMaterial.SetOverrideTag("RenderType", "Transparent"); // 设置渲染类型标签为透明targetMaterial.SetInt("_Blend", 1); // 设置混合模式为透明targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); // 设置源混合模式为源透明度targetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); // 设置目标混合模式为 1 - 源透明度targetMaterial.SetInt("_ZWrite", 0); // 禁用深度缓冲区写入(透明物体通常不写入深度缓冲区)targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; // 设置渲染队列为透明物体渲染队列targetMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); // 启用透明表面类型关键字Color color = targetMaterial.GetColor("_BaseColor"); // 获取材质的基础颜色color.a = alpha; // 设置透明度为传入的 alpha 值targetMaterial.SetColor("_BaseColor", color); // 更新材质的颜色}
  • 设置材质属性

    • targetMaterial.SetFloat("_Surface", 1):将材质的 _Surface 属性设置为 1,表示材质为透明(Transparent)。
    • targetMaterial.SetOverrideTag("RenderType", "Transparent"):设置渲染类型标签为透明。
    • targetMaterial.SetInt("_Blend", 1)targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha)targetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha):这些设置指定了透明物体的混合模式(使用源透明度和目标透明度的反向混合)。
    • targetMaterial.SetInt("_ZWrite", 0):禁用 Z 缓冲区写入(透明物体通常不写入深度缓冲区,以便能够看到背后的物体)。
    • targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent:设置渲染队列为透明物体渲染队列。
    • targetMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"):启用透明表面类型的关键词。
  • 透明度值调整

    • Color color = targetMaterial.GetColor("_BaseColor"); color.a = alpha; targetMaterial.SetColor("_BaseColor", color);:根据传入的 alpha 值(透明度)设置材质的颜色透明度。alpha 在 0 到 1 之间,0 表示完全透明,1 表示完全不透明。

动态调整的话,核心就是在触发时,通过调整color.a的值来实现。

三、完整代码

上面示例中使用滑动条来调整透明度的完整代码如下:

using UnityEngine;
using UnityEngine.UI;public class MaterialTransparencySlider : MonoBehaviour
{private Material targetMaterial; // 当前对象的材质private MeshRenderer meshRenderer; // 用于控制影子public Slider transparencySlider; // Slider 控件public Text textOpacity;void Start(){// 获取 MeshRenderermeshRenderer = GetComponent<MeshRenderer>();if (meshRenderer != null){targetMaterial = meshRenderer.material; // 获取材质实例}else{Debug.LogError("未找到 GameObject 上的 MeshRenderer。");return;}if (transparencySlider != null){// 监听 Slider 值变化事件transparencySlider.onValueChanged.AddListener(UpdateMaterialTransparency);// 初始化材质状态UpdateMaterialTransparency(transparencySlider.value);}else{Debug.LogError("未分配透明度滑动条 (Slider)。");}}/// <summary>/// 根据 Slider 的值动态更新材质透明度/// </summary>/// <param name="value">Slider 的当前值(范围 0-1)</param>public void UpdateMaterialTransparency(float value){if (targetMaterial == null || meshRenderer == null) return;if (value >= 1f){// 设置材质为完全不透明SetMaterialOpaque();}else{// 设置材质为透明,并调整透明度SetMaterialTransparent(value);}// 更新影子状态UpdateShadows(value);// 更新texttextOpacity.text = $"透明度={value * 100}";}/// <summary>/// 设置材质为完全不透明/// </summary>private void SetMaterialOpaque(){targetMaterial.SetFloat("_Surface", 0); // 设置材质为不透明,0 = OpaquetargetMaterial.SetOverrideTag("RenderType", "Opaque"); // 设置渲染类型标签为不透明targetMaterial.SetInt("_Blend", 0); // 设置混合模式为不透明targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); // 设置源混合模式为 OnetargetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // 设置目标混合模式为 ZerotargetMaterial.SetInt("_ZWrite", 1); // 启用深度缓冲区写入(不透明物体需要写入深度缓冲区)targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry; // 设置渲染队列为几何体渲染队列(不透明物体)targetMaterial.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); // 禁用透明表面类型关键字Color color = targetMaterial.GetColor("_BaseColor"); // 获取材质的基础颜色color.a = 1f; // 设置透明度为 1,完全不透明targetMaterial.SetColor("_BaseColor", color); // 更新材质的颜色}/// <summary>/// 设置材质为透明,并动态调整透明度/// </summary>/// <param name="alpha">透明度值(0-1)</param>private void SetMaterialTransparent(float alpha){targetMaterial.SetFloat("_Surface", 1); // 设置材质为透明,1 = TransparenttargetMaterial.SetOverrideTag("RenderType", "Transparent"); // 设置渲染类型标签为透明targetMaterial.SetInt("_Blend", 1); // 设置混合模式为透明targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); // 设置源混合模式为源透明度targetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); // 设置目标混合模式为 1 - 源透明度targetMaterial.SetInt("_ZWrite", 0); // 禁用深度缓冲区写入(透明物体通常不写入深度缓冲区)targetMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; // 设置渲染队列为透明物体渲染队列targetMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); // 启用透明表面类型关键字Color color = targetMaterial.GetColor("_BaseColor"); // 获取材质的基础颜色color.a = alpha; // 设置透明度为传入的 alpha 值targetMaterial.SetColor("_BaseColor", color); // 更新材质的颜色}/// <summary>/// 动态更新影子显示状态/// </summary>/// <param name="alpha">透明度值(0-1)</param>private void UpdateShadows(float alpha){if (alpha <= 0f){// 完全透明时禁用影子meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;}else{// 非完全透明时启用影子meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;}}private void OnDestroy(){// 移除监听事件以避免内存泄漏if (transparencySlider != null){transparencySlider.onValueChanged.RemoveListener(UpdateMaterialTransparency);}}
}

四、存在的问题

1. 可见问题:球1是手动设置的完全透明的材质,它与球4透明度为0时的状态还是有区别的。球1是可见的,而球4是完全不可见的。

2. 影子问题:球1和球2,是手动设置的透明材质,没有影子。球4在动态设置为透明材质时,仍然会有影子。最后透明度为0时影子消失,是在代码里处理的。

这两上问题有待进一下研究。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Ubuntu 22.04上搭建Kubernetes集群

Kubernetes 简介 什么是 Kubernetes&#xff1f; Kubernetes&#xff08;常简称为 K8s&#xff09;是一个强大的开源平台&#xff0c;用于管理容器化应用程序的部署、扩展和运行。它最初由 Google 设计并捐赠给 Cloud Native Computing Foundation&#xff08;CNCF&#xff0…

安卓录屏软件添加隐藏按钮

again.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.an…

批量导出图片,按商品货号命名图片名-Excel易用宝

我们部门有这样一份商品信息表&#xff0c;包含着商品名称&#xff0c;货号和商品对应的图片&#xff0c;现在需要将这些商品图片导出&#xff0c;并且以对应的货号命名图片发给客户。 如果通过在图片上右键“另存为图片”&#xff0c;这样一张一张图片处理效率也太低了。 Exc…

关于SpringBoot项目创建后构建总是失败的问题

第一个问题&#xff1a;IDEA创建项目总是失败 原因&#xff1a;创建项目的时候默认使用的是https://start.spring.io&#xff0c;这个是一个外国网站&#xff0c;众所周知的就是国内访问总是出现不稳定的现象&#xff0c;这就是导致项目创建失败的最终原因。 解决方法&#x…

彻底理解布隆过滤器怎么解决缓存穿透问题

一.应用场景 实际业务中使用Redis&#xff0c;都是先通过用户插入数据到Mysql中&#xff0c;然后更新缓存到Redis&#xff0c;下一次用户再查询该数据的时候就可以通过Redis来进行查询。 先看下图&#xff0c;是假设的一个用户查询的场景&#xff1a; 首先用户查询的时候会去缓…

Leetcode数学部分笔记

Leetcode数学部分笔记 1. 回文数2. 加一3. 阶乘后的零4. x 的平方根5. Pow(x, n) 1. 回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&…

大数据技术之新能源汽车数仓【附学习资源】

第一章 新能源汽车数仓的背景与意义 1.1 新能源汽车产业的爆发式增长 新能源汽车产业近年来呈现出爆发式增长&#xff0c;主要得益于全球范围内对环境保护和能源转型的高度重视。随着全球多个国家和地区对碳排放进行严格控制&#xff0c;政策层面的支持为新能源汽车的普及提供…

Nature:ChatGPT助力学术写作的方法

随着生成式AI技术的飞速发展&#xff0c;它在科研中的潜力也逐渐被探索和实践。在Nature最近的一篇文章里&#xff0c;Dritjon Gruda 副教授提到&#xff0c;生成式AI不仅在论文写作和编辑中扮演着越来越重要的角色&#xff0c;帮助科研人员提高工作效率&#xff0c;还在同行评…

分布式 分布式事务 总结

前言 相关系列 《分布式 & 目录》《分布式 & 分布式事务 & 总结》《分布式 & 分布式事务 & 问题》 分布式事务 所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言&#xff0c;一次完整的交易需要同时调动两个节…

UnityShaderLab 实现黑白着色器效果

实现思路&#xff1a;取屏幕像素的RGB值&#xff0c;将三个通道的值相加&#xff0c;除以一个大于值使颜色值在0-1内&#xff0c;再乘上一个强度值调节黑白强度。 在URP中实现需要开启Opaque Texture ShaderGraph实现&#xff1a; ShaderLab实现&#xff1a; Shader "Bl…

机器人的动力学前馈控制

机器人前馈技术可加快伺服驱动器内部的误差收敛速度&#xff0c;进而改善机器人的动态响应特性&#xff0c;解决机器人在运动过程中的抖动问题&#xff0c;提升机器人系统的精度和效率。 对于关节型机器人而言&#xff0c;在理想的刚性连接下&#xff0c;若给定每个关节所需要的…

Java基础——多线程基础

一、线程介绍 程序&#xff1a;是为完成特定任务&#xff0c;用某种语言编写的一组指令的集合。简单地说&#xff0c;就是我们写的代码进程&#xff1a; 进程是指运行中的程序&#xff0c;比如我们使用qq&#xff0c;就启动了一个进程。操作系统会为该进程分配内存空间。当我们…

在本地运行大语言模型

1&#xff0c;打开下面网站下载&#xff0c;软件 lm studio 2&#xff0c; 设置模型下载路径 3&#xff0c;没有魔法条件的人&#xff0c;去镜像网站下载模型的镜像文件 、 4&#xff0c;

JUC:Synchronized和锁升级

1. 面试题 谈谈你对Synchronized的理解Sychronized的锁升级你聊聊Synchronized实现原理&#xff0c;monitor对象什么时候生成的&#xff1f;知道monitor的monitorenter和monitorexit这两个是怎么保证同步的嘛&#xff1f;或者说这两个操作计算机底层是如何执行的偏向锁和轻量级…

网络知识:IP数据报知识详解

目录 一、IP数据报概念 二、IPV4数据报报头组成 三、IPV6数据报报头组成 今天给大家分享IP数据库相关的知识,希望对大家进一步了解IP协议提供一些帮助! 一、IP数据报概念 TCP/IP协议的网际层接收到传输层传递过来的数据单元,封装成向下(OSI模型的数据链路层、TCP/IP协…

消息中间件-Kafka2-3.9.0源码构建

消息中间件-Kafka2-3.9.0源码构建 1、软件环境 JDK Version 1.8Scala Version 2.12.0Kafka-3.9.0 源码包 下载地址&#xff1a;https://downloads.apache.org/kafka/3.9.0/kafka-3.9.0-src.tgzGradle Version > 8.8Apache Zookeeper 3.7.0 2、源码编译 打开源码根目录修改…

详解:HTTP/HTTPS协议

HTTP协议 一.HTTP是什么 HTTP&#xff0c;全称超文本传输协议&#xff0c;是一种用于分布式、协作式、超媒体信息系统的应用层协议。HTTP往往是基于传输层TCP协议实现的&#xff0c;采用的一问一答的模式&#xff0c;即发一个请求&#xff0c;返回一个响应。 Q&#xff1a;什…

vue中pdf.js的使用,包括pdf显示,跳转指定页面,高亮关键词

目录 一、下载pdf.js 二、引入到本地的项目中 三、实现预览pdf 四、跳转到指定页面 五、利用pdf里面的find查找关键词并可以监听updatefindcontrolstate统计个数 六、修改页面大小为实际大小 七、每次加载pdf都是在第一页 八、修改pdf滚动方式为横向 九、清除pdf缓存 十、pdf.j…

题海拾贝:力扣 231. 2 的幂

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《题海拾贝》、《数据结构与算法之美》 欢迎点赞&#xff0c;关注&#xff01; 目录 …

多级IIR滤波效果(BIQUAD),system verilog验证

MATLAB生成IIR系数 采用率1k&#xff0c;截止频率30hz&#xff0c;Matlab生成6阶对应的biquad3级系数 Verilog测试代码 // fs1khz,fc30hz initial beginreal Sig_Orig, Noise_white, Mix_sig;real fs 1000;Int T 1; //周期int N T*fs; //1s的采样点数// 数组声明…