在项目开发过程中,遇到过这样一个需求,就是复杂仪器介绍的时候,需要透明化其他部位,显示当前介绍部位,自己封装了一个脚本:
1.思路:将仪器的所有材质存下来,然后按需改变想要透明化的部位材质属性为透明,当前介绍的部位材质不变
2.使用方法:将仪器分部位,然后将下面的脚本挂在部位上
3.效果如下:
/*******************************************************************************
* 版权声明:北京润尼尔网络科技有限公司,保留所有版权
* 版本声明:v1.0.0
* 类 名 称: test
* 创建日期:2019-08-02 19:52:57
* 作者名称:静哥哥
* CLR 版本:4.0.30319.42000
* 修改记录:
* 描述:改变模型状态脚本:点击模型部位按钮,当前点击的模型颜色正常显示,其他的部件透明化显示
******************************************************************************/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Com.Rainier.WangJing
{
public class ChangeModelStateEvent : MonoBehaviour
{
public static ChangeModelStateEvent Instance;
/// <summary>
/// 透明材质
/// </summary>
public Material transparentMaterial;
/// <summary>
/// 获取当前物体的所有子物体的孙物体
/// </summary>
public Transform[] objs;
/// <summary>
/// 自带mesh的所有子物体和孙物体
/// </summary>
public List<GameObject> meshs=new List<GameObject>();
/// <summary>
/// 自带mesh的所有子物体和孙物体的材质
/// </summary>
public List<List<Material>> allMaterial=new List<List<Material>>();
public List<List<Shader>> allShader = new List<List<Shader>>();
public Shader transparentShader;
/// <summary>
/// 每次激活的时候重置设备状态
/// </summary>
private void OnEnable()
{
OriginalMaterial();
}
private void Awake()
{
Instance = this;
}
void Start ()
{
if (transparentMaterial == null)
{
transparentMaterial = Resources.Load<Material>("transparentMaterial");
transparentShader = transparentMaterial.shader;
}
InitList();
}
/// <summary>
/// 数据存储:初始化列表数据
/// </summary>
private void InitList()
{
//获取当前物体的子物体的孙物体
objs = GetComponentsInChildren<Transform>();
//过滤(将当前物体的所有子物体和孙物体中带有Mesh组件的物体的所有材质存在一个材质列表)
for (int i = 0; i < objs.Length; i++)
{
GameObject a = objs[i].gameObject;
List<Material> m = new List<Material>();
List<Shader> s = new List<Shader>();
if (a.GetComponent<MeshRenderer>())
{
meshs.Add(a);
for (int j = 0; j < a.GetComponent<MeshRenderer>().materials.Length; j++)
{
//注意:
Material material = new Material(a.GetComponent<MeshRenderer>().materials[j]);
Shader shader = material.shader;
//Material material = a.GetComponent<MeshRenderer>().materials[j];
m.Add(material);
s.Add(shader);
}
//将所有带mesh的物体的材质列表存在一个大的列表中
allMaterial.Add(m);
allShader.Add(s);
}
}
//测试用:打印当前获取的所有材质名称
//for (int i = 0; i < allMaterial.Count; i++)
//{
// for (int j = 0; j < allMaterial[i].Count; j++)
// {
// Debug.Log("当前获取到的所有材质为:" + allMaterial[i][j].name);
// }
//}
}
/// <summary>
/// 透明材质
/// </summary>
public void TransparentMaterial()
{
//将当前物体带mesh的所有子物体和孙物体的所有材质设置为透明
for (int i = 0; i < meshs.Count; i++)
{
for (int j = 0; j < meshs[i].GetComponent<MeshRenderer>().materials.Length; j++)
{
meshs[i].GetComponent<MeshRenderer>().materials[j].shader = transparentShader;
meshs[i].GetComponent<MeshRenderer>().materials[j].CopyPropertiesFromMaterial(transparentMaterial);
}
}
}
/// <summary>
/// 恢复原来的材质
/// </summary>
public void OriginalMaterial()
{
Debug.Log("mesh的数量:"+ meshs.Count+"材质组的数量:"+ allMaterial.Count);
for (int i = 0; i < meshs.Count; i++)
{
for (int j = 0; j < meshs[i].GetComponent<MeshRenderer>().materials.Length; j++)
{
meshs[i].GetComponent<MeshRenderer>().materials[j].shader = allShader[i][j];
meshs[i].GetComponent<MeshRenderer>().materials[j].CopyPropertiesFromMaterial(allMaterial[i][j]);
}
}
}
private void Update()
{
//if(Input.GetKeyDown(KeyCode.T))
//{
// TransparentMaterial();
//}
//if(Input.GetKeyDown(KeyCode.O))
//{
// OriginalMaterial();
//}
}
}
}
使用方法很简单,时间有限先不多说,欢迎批评指正!谢谢!