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

相关文章

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

遮罩,在指定元素上进行遮罩

废话不多说,直接上代码: ps:依赖 jquer.js 1.首先,定义一个 Overlay.js  代码如下: /*遮罩 Overlay js 对象*/function Overlay(options){//{targetId:'',viewHtml:'',viewWidth:'',viewHeight:''}try{this.state=false;//遮罩状态 true 激活,f

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t