Unity材質丟失?用腳本自動解決吧!

unity HDRP的editor腳本來處理材質丟失問題
最近初學houdini,發現houdini digital asset導入到unity HDRP中材質出錯,平時從max導fbx文件到unity中,也常常發現一些材質丟失,不支持,於是我寫了一個unity的editor腳本來處理這種事情,核心步驟如下:
1.找到選中物體及其所有子物體的材質
2.將這些材質的shader替換成爲HDRP的Lit Shader。
此外還有兩個功能,一個是將選中物體及其子物體都共用一個材質,這個在靜態合批時比較有用。另一個功能是將選中物體中所有丟失材質的物體,賦予一個共用的材質,這樣也是考慮到可以在靜態合批時有用,因爲例如車的模型內部有很多瑣碎的材質表現座椅、內飾等細節,但是這些材質可能相似度很高,而且作爲外景裝飾,也看不太到,所以我把這些都合成了一個共用的材質,一併去表現。
中間遇到一個比較搞的問題是material 和sharedmaterial 的區別,之前看過又忘記了╮(╯▽╰)╭, material會在腳本調用時實例化一個材質出來,所以運行時纔會生效,sharedmaterial是相當於直接更改的asset面板的材質,不需運行也可以生效,並且所有引用這個材質的物體都會跟着立即改變。
基本上對我來說,還是很實用的,畢竟這一片丟材質的粉紅,實在是太難看了…
修好了就賊開心,自動化的工具就是好用呀!
左圖丟失部分材質,右邊一鍵直接全部自動修好

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class resetMat : MonoBehaviour//直接將腳本複製到asset文件夾中即可在工具欄發現該工具
{
    public GameObject ob;
    [MenuItem("Gq_Tools/修復材質球shader丟失")]
    static void StartRun1()
    {
        var objs = Selection.objects;
        foreach (var obj in objs)
        {
            var go = obj as GameObject;
            var rs = go.GetComponentsInChildren<Renderer>();
            foreach (var r in rs)
            {
               Material [] shaderArr = new Material[r.materials.Length];
                shaderArr = r.materials;
                print("    DDDDD" + shaderArr.Length);
                for (int i=0;i<shaderArr.Length;i++)
                {
                    shaderArr[i].shader=Shader.Find("HDRP/Lit");
                }
            }
        }
    }
    [MenuItem("Gq_Tools/將選中物體都賦予同一材質球")]
    static void StartRun2()
    {
        Material newmat = new Material(Shader.Find("HDRP/Lit"));

        newmat.color = new Color(255, 228, 0, 1);

        var objs = Selection.objects;
        foreach (var obj in objs)//for每個選中的物體
        {
            var go = obj as GameObject;
            var rs = go.GetComponentsInChildren<Renderer>();//連帶子物體
            foreach (var r in rs)//每個物體及子物體的renderer
            {
                Material[] matArr = new Material[r.materials.Length];
                matArr = r.materials;
                r.material = newmat;
            }
        }
    }
    [MenuItem("Gq_Tools/將所有丟失材質都強制賦予一個共用的材質")]
    static void StartRun3()
    {    Material newmat = new Material(Shader.Find("HDRP/Lit"));
        var objs = Selection.objects;
        foreach (var obj in objs)
        {
            var go = obj as GameObject;
            var rs = go.GetComponentsInChildren<Renderer>();
            foreach (var r in rs)//每個物體及子物體的renderer組件
            {
               // Material[] matArr = new Material[r.sharedMaterials.Length];
               // matArr = r.materials;
                if (r.sharedMaterial==null)//如果有丟失材質球的坑
                {
                    print("丟失材質");
                    
                    r.sharedMaterial = newmat;

                }
                else { print("沒有丟失"); }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章