在項目開發過程中,遇到過這樣一個需求,就是複雜儀器介紹的時候,需要透明化其他部位,顯示當前介紹部位,自己封裝了一個腳本:
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();
//}
}
}
}
使用方法很簡單,時間有限先不多說,歡迎批評指正!謝謝!