Unity中物体半透明显示——e.g.让指定的构件从所有构件中脱颖而地展示自我

本文主要是介绍Unity中物体半透明显示——e.g.让指定的构件从所有构件中脱颖而地展示自我,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、要达到的效果

用户点击【走廊】菜单的时候,其他部件穿透显示,只有走廊正常显示,并高亮闪烁。
请添加图片描述

二、思路

  • 1、读取材质信息:读取各个部件的材质信息并存储,恢复材质的时候用
  • 2、设置物体为透明:把物体原来的材质换成透明材质
  • 3、取消物体的透明:把物体的透明材质换成原来的材质

三、关键步骤的代码

  • 只列了关键的方法

1、提取物体的材质生成一个字典

    /// <summary>/// 给定一个设备(3d物体root),遍历该物体的所有子部件(子部件的root名字包含[#],命名格式如【#部件名字】),读取子部件物体的材质信息,返回一个字典:/// Dictionary<string-部件的物体名字, List<(GameObject, Material[])-物体和它的材质数组>>/// key用物体名字是用来快速提取某个子部件的材质信息,用于更换材质或者恢复材质/// /// 层级关系及命名/// root///     #部件1///        gameobject1///        gameobject2///        ...///        gameobjectn///     ...///     #部件n/// /// </summary>/// <param name="root">3d物体——部件的root</param>/// <returns> Dictionary<string-子部件名字, List<(GameObject -- 子部件的子物体, Material[] -- 物体对应的材质数组)>>  </returns>static Dictionary<string, List<(GameObject, Material[])>> GetMaterialsDict(GameObject root){//提前生成空的返回值var partsMaterialDict = new Dictionary<string, List<(GameObject, Material[])>>();//获取所有的零件var parts = root.GetComponentsInChildren<Transform>(true).Where(x => x.name.Contains('$')).ToList();Debug.Log(parts.Count);Debug.Log(parts.Select(x => x.name.Split('$')[1]).First());parts.ForEach(x => Debug.Log(x.name.Split('$')[1]));//每个零件获取它的子物体的材质信息parts.ForEach(part =>{var partName = part.name.Split('$')[1];List<(GameObject, Material[])> goMatList = new List<(GameObject, Material[])>();part.GetComponentsInChildren<Transform>().ToList().ForEach(p =>{//Debug.Log(p.GetComponent<Renderer>());if (p.GetComponent<Renderer>() != null){goMatList.Add((p.gameObject, p.GetComponent<Renderer>().materials));}});partsMaterialDict[partName] = goMatList;});partsMaterialDict.Keys.ToList().ForEach(x =>{Debug.Log($"======{x}====== {partsMaterialDict[x].Count}");});return partsMaterialDict;}

2、其它物体设置成半透明

var partsMaterialDict = GetMaterialsDict(root);  //设备零部件的的父节点
 partsMaterialDict.ToList().Where(x => x.Key != name)   //给定的名字.SelectMany(x => x.Value).ToList().ForEach(x =>{//x.Item1.GetComponent<MeshRenderer>().sharedMaterials = new Material[] { transMat }; //此处有bug,数量要做一致x.Item1.GetComponent<MeshRenderer>().sharedMaterials = x.Item1.GetComponent<MeshRenderer>().sharedMaterials.Select(x => transMat).ToArray();//生成对数量的透明材质数组}); 

3、所有物体设置为正常材质

partsMaterialDict.ToList().SelectMany(x => x.Value).ToList()   //展开成1d数组.ForEach(x => x.Item1.GetComponent<MeshRenderer>().sharedMaterials = x.Item2);

4、展示一个部件

  • 1、显示全貌
  • 2、等待1秒
  • 3、其它半透明显示,自己正常显示,且高亮
 /// <summary>/// 显示指定的构件/// 指定构件从所有构件中脱颖而出(其他的透明显示,自己正常显示),高亮显示自己。/// 1、显示全貌/// 2、其它半透明显示,自己正常显示,且高亮/// </summary>/// <param name="name">部件名字</param>/// <param name="partsMaterialDict">部件的【物体】【材质信息】字典</param>/// <param name="transMat">透明材质</param>/// <param name="partsInfos">部件信息表</param>/// <returns>UniTask</returns>public static async UniTask Show(string name, Dictionary<string, List<(GameObject, Material[])>> partsMaterialDict, Material transMat, List<PartsInfo> partsInfos){//【1】显示所有【还原材质】partsMaterialDict.ToList().SelectMany(x => x.Value).ToList().ForEach(x => x.Item1.GetComponent<MeshRenderer>().sharedMaterials = x.Item2);//【2】关闭所有的高亮partsInfos.ForEach(x => x.part3D.GetComponent<Highlighter>().tween = false);await UniTask.Delay(TimeSpan.FromSeconds(1));//【3】其它半透明partsMaterialDict.ToList().Where(x => x.Key != name).SelectMany(x => x.Value).ToList().ForEach(x =>{//x.Item1.GetComponent<MeshRenderer>().sharedMaterials = new Material[] { transMat }; //此处有bug,数量要做一致x.Item1.GetComponent<MeshRenderer>().sharedMaterials = x.Item1.GetComponent<MeshRenderer>().sharedMaterials.Select(x => transMat).ToArray();//生成对数量的透明材质数组});//【4】自己高亮显示        partsInfos.Where(x => x.name == name).First().part3D.GetComponent<Highlighter>().tween = true;}

5、其它用到的数据结构

   /// <summary>/// 构件信息/// </summary>[Serializable]public class PartsInfo{/// <summary>/// 构件名字/// </summary>[Header("构件名字")][SerializeField]public string name;/// <summary>/// 菜单button/// </summary>[Header("菜单button")][SerializeField]public Button button;/// <summary>/// 构件的3D物体/// </summary>[Header("构件的3D物体")][SerializeField]public GameObject part3D;/// <summary>/// 是否学习过/// </summary>[Header("是否学习过")][SerializeField]public bool hasStudied;}/// <summary>/// 部件信息表/// </summary>[Header("部件信息表")][SerializeField]public List<PartsInfo> partsInfos = new List<PartsInfo>();

这篇关于Unity中物体半透明显示——e.g.让指定的构件从所有构件中脱颖而地展示自我的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653199

相关文章

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.