unity替换模型材质

 我们用一个柜门的模型做例子,这个模型一共有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;
            }
        }
    }
}

效果:

效果完成。 

猜你喜欢

转载自blog.csdn.net/qq_42345116/article/details/121495947