?我们用一个柜门的模型做例子,这个模型一共有8个材质,正常思路是通过获取模型的Meshenderer组件下的Materials中的材质,然后将这些材质替换成图片中cube的红色材质?
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
public class Test : MonoBehaviour
{
public Transform obj;
public Material tmMat; //透明材质
void Start()
{
//获取全部材质
for (int i = 0; i < obj.GetComponent<MeshRenderer>().materials.Length; i++)
{
obj.GetComponent<MeshRenderer>().materials[i] = tmMat; //一个一个替换成透明材质
}
}
}
?运行后发现效果并没有改变:
?为什么呢?因为材质替换是通过传递一个材质数组进行计算的,所以一个一个替换无法完成效果
Note that like all arrays returned by Unity, this returns a copy of materials array. If you want to change some materials in it, get the value, change an entry and set materials back.
知道原因了,我们在来修改一下代码
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
public class Test : MonoBehaviour
{
public Transform obj;
public Material tmMat; //透明材质
Material[] newTmMatArray;//透明材质数组
void Start()
{
newTmMatArray = new Material[obj.GetComponent<MeshRenderer>().materials.Length];//数组初始化长度
//获取全部材质
for (int i = 0; i < newTmMatArray.Length; i++)
{
newTmMatArray[i] = tmMat;
}
obj.GetComponent<MeshRenderer>().materials = newTmMatArray;//将透明数组赋给模型材质
}
}
效果:哈哈 成功。
?接下来优化一下,一个机柜由 前后柜门和柜体组成,按下J键让模型透明,按下K键让模型复原,
?思路:
1.创建一个 TMObj类,该类用来存储单个模型 和 这个模型的原材质数组,并且在新建类的时候通过构造给两个字段赋值
//透明模型 数据
public class TMObj
{
public Transform obj;//模型
public Material[] objMatArray;//模型原材质(用于还原透明)
public TMObj(Transform _obj)
{
obj = _obj;
objMatArray = new Material[obj.GetComponent<MeshRenderer>().materials.Length];
for (int i = 0; i < obj.GetComponent<MeshRenderer>().materials.Length; i++)
{
objMatArray[i] = obj.GetComponent<MeshRenderer>().materials[i];
}
}
}
2.添加List<TransForm> objList 和List<TMObj> tmObjList字段.objList存储机柜的 前后柜门和柜体,开始时遍历这个list字段列表,将TMObj这个类充当数据用,添加到tmObjList中
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
public class Test : MonoBehaviour
{
public Material tmMat; //透明材质
public List<Transform> objList;
public List<TMObj> tmObjList;
Material[] newTmMatArray;//透明材质数组
void Start()
{
tmObjList = new List<TMObj>();
for (int i = 0; i < objList.Count; i++)
{
TMObj tmObj = new TMObj(objList[i]);
tmObjList.Add(tmObj);
}
}
}
3.在Update中设置按下J键透明,K键还原
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
public class Test : MonoBehaviour
{
public Material tmMat; //透明材质
public List<Transform> objList;
public List<TMObj> tmObjList;
Material[] newTmMatArray;//透明材质数组
void Start()
{
tmObjList = new List<TMObj>();
for (int i = 0; i < objList.Count; i++)
{
TMObj tmObj = new TMObj(objList[i]);
tmObjList.Add(tmObj);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.J))
{
Debug.Log("透明");
for (int i = 0; i < tmObjList.Count; i++)
{
newTmMatArray = new Material[tmObjList[i].obj.GetComponent<MeshRenderer>().materials.Length];
for (int j = 0; j < tmObjList[i].obj.GetComponent<MeshRenderer>().materials.Length; j++)
{
newTmMatArray[j] = tmMat;
}
tmObjList[i].obj.GetComponent<MeshRenderer>().materials = newTmMatArray;
}
}
if (Input.GetKeyDown(KeyCode.K))
{
Debug.Log("不透明");
for (int i = 0; i < tmObjList.Count; i++)
{
tmObjList[i].obj.GetComponent<MeshRenderer>().materials = tmObjList[i].objMatArray;
}
}
}
}
效果:
效果完成。?
|