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

news2024/12/26 21:12:22

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

一、手动设置的方法

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

物体的透明与否是通过材质来设置的。只有我们把具有透明度的材质指给物体的渲染器(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 = Opaque
        targetMaterial.SetOverrideTag("RenderType", "Opaque"); // 设置渲染类型标签为不透明
        targetMaterial.SetInt("_Blend", 0); // 设置混合模式为不透明
        targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); // 设置源混合模式为 One
        targetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // 设置目标混合模式为 Zero
        targetMaterial.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 = 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); // 设置目标混合模式为 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()
    {
        // 获取 MeshRenderer
        meshRenderer = 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);

        // 更新text
        textOpacity.text = $"透明度={value * 100}";
    }

    /// <summary>
    /// 设置材质为完全不透明
    /// </summary>
    private void SetMaterialOpaque()
    {
        targetMaterial.SetFloat("_Surface", 0); // 设置材质为不透明,0 = Opaque
        targetMaterial.SetOverrideTag("RenderType", "Opaque"); // 设置渲染类型标签为不透明
        targetMaterial.SetInt("_Blend", 0); // 设置混合模式为不透明
        targetMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); // 设置源混合模式为 One
        targetMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // 设置目标混合模式为 Zero
        targetMaterial.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 = 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); // 设置目标混合模式为 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.coloradmin.cn/o/2255452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java课程设计项目-servlet+jsp美食系统、菜品管理系统

文章目录 Java课程设计项目-servletjsp美食系统一、项目介绍二、技术介绍2.1 环境需要2.2 技术栈 环境需要三、功能实现3.1登录注册3.2首页菜品展示、轮播图3.3美食菜品分类、查询3.4作品动态、个人简介、菜品收藏3.5创建菜谱、添加步骤 四、系统代码展示4.1项目架构&#xff0…

掌握时间,从`datetime`开始

文章目录 掌握时间&#xff0c;从datetime开始第一部分&#xff1a;背景介绍第二部分&#xff1a;datetime库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前日期和时间2. 创建特定的日期3. 计算两个日期…

前端技术(23) : 聊天页面

来源: GPT生成之后微调 效果图 HTML代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>聊天</t…

ubuntu的matlab使用心得

1.读取视频 v VideoReader(2222.mp4);出问题&#xff0c;报错&#xff1a; matlab 错误使用 VideoReader/initReader (第 734 行) 由于出现意外错误而无法读取文件。原因: Unable to initialize the video properties 出错 audiovideo.internal.IVideoReader (第 136 行) init…

基于SpringBoot+Vue框架的在线考试系统的设计与实现

基于SpringBootVue框架的在线考试系统的设计与实现 系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环…

软错误防护技术在车规MCU中应用

在大气层内&#xff0c;宇宙射线粒子与大气分子发生核反应生成大气中子。大气中子入射微电子器件或电路将会诱发单粒子效应&#xff08;SEE&#xff09;&#xff0c;效应类型主要有单粒子翻转&#xff08;SEU&#xff09;、单粒子瞬态&#xff08;SET&#xff09;、单粒子锁定&…

【数据中心建设资料】数据中心安全建设解决方案,数据中心整理解决方案,数据中心如何做到安全保障,数据中台全方案(Word全原件)

第一章 解决方案 1.1 建设需求 1.2 建设思路 1.3 总体方案 信息安全系统整体部署架构图 1.3.1 IP准入控制系统 1.3.2 防泄密技术的选择 1.3.3 主机账号生命周期管理系统 1.3.4 数据库账号生命周期管理系统 1.3.5 双因素认证系统 1.3.6 数据库审计系统 1.3.7 数据脱敏系统 1.3.8…

WLAN AutoConfig服务假死?重启服务恢复网络连接!

目录 背景&#xff1a; 过程&#xff1a; 可能引起原因&#xff1a; 具体解决步骤&#xff1a; 方法一&#xff1a; 方法二&#xff1a; 总结&#xff1a; 背景&#xff1a; 这个问题困扰我好长一段时间了&#xff0c;每次下班将电脑关机后&#xff0c;次日早上电脑开机…

Hadoop生态圈框架部署 伪集群版(六)- MySQL安装配置

文章目录 前言一、MySQL安装与配置1. 安装MySQL2. 安装MySQL服务器3. 启动MySQL服务并设置开机自启动4. 修改MySQL初始密码登录5. 设置允许MySQL远程登录6. 登录MySQL 卸载1. 停止MySQL服务2. 卸载MySQL软件包3. 删除MySQL配置文件及数据目录 前言 在本文中&#xff0c;我们将…

运用蓝光三维扫描仪的艺术与科技的完美融合-石膏头像模型3D扫描真实复刻

石膏头像具有独特的魅力&#xff0c;每一处细节都彰显着艺术之美。无论是深邃的眼神&#xff0c;还是精致的轮廓&#xff0c;都让人陶醉其中。 随着雕塑形式的日渐丰富&#xff0c;越来越多的新材料和新的塑造手法被运用到雕塑创作中&#xff0c;蓝光三维扫描技术的应用&#…

【大语言模型】ACL2024论文-24 图像化歧义:Winograd Schema 挑战的视觉转变

【大语言模型】ACL2024论文-24 图像化歧义&#xff1a;Winograd Schema 挑战的视觉转变 目录 文章目录 【大语言模型】ACL2024论文-24 图像化歧义&#xff1a;Winograd Schema 挑战的视觉转变目录摘要研究背景问题与挑战如何解决核心创新点算法模型实验效果&#xff08;包含重要…

深入浅出:Gin框架路由与HTTP请求处理

深入浅出&#xff1a;Gin框架路由与HTTP请求处理 引言 在Web开发中&#xff0c;路由和HTTP请求处理是构建API的核心部分。Gin框架作为Go语言中最受欢迎的Web框架之一&#xff0c;提供了简洁而强大的工具来处理这些任务。本文将深入浅出地介绍如何使用Gin框架进行路由定义、处…

vscode + cmake 管理员权限调试

Ubuntu 22.04 使用 VsCode CMake 开发 ICMP ping 功能&#xff0c;执行到下面的语句时报错&#xff1a; socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); --------------------------------------- 程序报错&#xff1a; Operation not permitted 查找原因&#xff0c;需要管理员权…

MATLAB数学建模之画图汇总

MATLAB是一种强大的数学软件&#xff0c;广泛应用于工程计算、控制设计、信号处理等领域。在数学建模中&#xff0c;MATLAB的绘图功能可以帮助我们直观地展示数据和模型结果。 1. 二维数据曲线图 1.1 绘制二维曲线的基本函数 plot函数用于绘制二维平面上的线性坐标曲线图&am…

李飞飞首个“空间智能”模型发布:一张图,生成一个3D世界 | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 在人工智能技术迅速发展的背景下&#xff0c;李飞飞创立的世界实验室于近期发布了首个“空间智能”模型&#xff0c;这一创新成果引发了3D生…

力扣--543.二叉树的直径

题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 代码 /** Definition for a binary tree node.public…

你是如何找bug的?bug分析的正确打开方式

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Bug严重级别(Severity&#xff0c;Bug级别)&#xff1a;是指因缺陷引起的故障对软件产品的影响程度&#xff0c;由测试人员指定。 A-Crash&#xff1a;造成系统或…

QT获取tableview选中的行和列的值

查询数据库数据放入tableview&#xff08;tableView_database&#xff09;后 QSqlQueryModel* sql_model new QSqlQueryModel(this);sql_model->setQuery("select * from dxxxb_move_lot_tab");sql_model->setHeaderData(0, Qt::Horizontal, tr("id&quo…

Github 2024-12-01 开源项目月报 Top20

根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…

python调用GPT-4o实时音频 Azure OpenAI GPT-4o Audio and /realtime

发现这块网上信息很少&#xff0c;记录一下 微软azure入口 https://learn.microsoft.com/zh-cn/azure/ai-services/openai/realtime-audio-quickstart?pivotsprogramming-language-ai-studio sdk文档 https://github.com/azure-samples/aoai-realtime-audio-sdk?tabread…