[Unity Editor]刪除FBX的默認(rèn)材質(zhì)

1掖棉、問題說明

項目中部分粒子系統(tǒng)(Particle System)需要用到Mesh仍翰,因此引入了一些為粒子系統(tǒng)提供Mesh的FBX冯凹。在性能測試時發(fā)現(xiàn)吉嚣,加載粒子總會伴隨著Standard Shader的編譯消耗梢薪。檢查下來發(fā)現(xiàn),F(xiàn)BX在導(dǎo)入Unity時會關(guān)聯(lián)上默認(rèn)材質(zhì)(Default-Material)然后引用內(nèi)建的標(biāo)準(zhǔn)Shader(Standard)尝哆。這個材質(zhì)和Shader是多余的秉撇,因為粒子系統(tǒng)使用的是Particle System - Renderer中設(shè)置的內(nèi)容。
  說明:我們沒有把Builtin Shader放入到工程中合并打包,所以會出現(xiàn)每次加載粒子都產(chǎn)生Shader編譯的耗時琐馆。如果對這類Shader做過處理规阀,可能不會看到這個現(xiàn)象,但是問題是存在的瘦麸。

2谁撼、深入測試

上面的問題是老大描述給我的,但是我自己進行測試時滋饲,并沒有發(fā)現(xiàn)這個現(xiàn)象厉碟。然后我們對比了測試代碼,發(fā)現(xiàn)這個問題發(fā)生在異步加載資源的時候屠缭。然而在我這異步加載也沒有復(fù)現(xiàn) Orz……
  后面對資源箍鼓、代碼進行了各種嘗試,發(fā)現(xiàn)了下面的一些條件(結(jié)論):

  1. 如果FBX和引用它的資源打到同一個AB里呵曹,這個AB不會包含F(xiàn)BX中多余的內(nèi)容款咖;如果FBX單獨打包,它會包含模型中的全部內(nèi)容逢并,比如:Material之剧、Shader、骨骼節(jié)點等砍聊。
  2. 加載粒子系統(tǒng)時使用LoadAssetAsync才會把多余Standard加載出來背稼。(加載AssetBundle使用LoadFromFile還是LoadFromFileAsync都無所謂)

項目中與此有關(guān)的用法有:
1.Particle System使用FBX中的Mesh
2.Animation直接使用FBX中的AnimationClip
  第2種用法通常會引入多余的骨骼節(jié)點,因為做動畫FBX的時候會帶著角色骨骼玻蝌。而實際使用時骨骼會單獨打包蟹肘,或和SkinnedMeshRenderer打在一起。這個情況也很好處理俯树,直接把AnimationClip從FBX中分離后再使用就可以帘腹。


【2017-9-12補充】
  FBX和引用它的資源打到同一個AB里有兩種情況,一種是只給引用FBX的資源設(shè)置ABName许饿,一種是給FBX和引用它的資源設(shè)置相同的ABName阳欲。對于前者,符合上面的結(jié)論1陋率;對于后者球化,它的情況和打包到兩個AB中是一樣的。
  這個情況也好理解瓦糟,當(dāng)給資源設(shè)置了ABName筒愚,就表示你需要這個資源的全部內(nèi)容,Unity無法替你過濾菩浙。

3巢掺、解決問題

解決Standard多次編譯的方法有好幾種句伶,比如合并打包Shader、破壞上述發(fā)生條件等陆淀。我們使用的是刪除FBX默認(rèn)導(dǎo)入的材質(zhì)考余。

  手動處理的話,可以勾選Import Materials倔约,然后刪除FBX同目錄下產(chǎn)生的Materials目錄秃殉。刪除后模型會變粉,請不要在意浸剩,我們需要的只有Mesh钾军。

4、代碼處理

終于到本文要介紹的內(nèi)容了...

public class ModelMatTool : AssetPostprocessor
{
    private static bool _needWaiting = false;

    /// <summary>
    /// 是否啟用刪除操作
    /// OnPostprocessModel回調(diào)在模型導(dǎo)入的時候就會調(diào)到绢要,
    /// 通過這個標(biāo)記位保證只在調(diào)用腳本函數(shù)的時候執(zhí)行吏恭。
    /// </summary>
    private static bool _enableDelete = false;

    /// <summary>
    /// 批量刪除模型上的材質(zhì)
    /// </summary>
    public static IEnumerator DelModelMats(Object[] models)
    {
        foreach (Object obj in models)
        {
            while (_needWaiting) yield return null;
            DelModelMat(obj as GameObject);
        }
    }

    /// <summary>
    /// 刪除模型上綁定的材質(zhì)
    /// </summary>
    /// <param name="model">模型對象</param>
    public static void DelModelMat(GameObject model)
    {
        if (null == model) return;
        string assetPath = AssetDatabase.GetAssetPath(model);
        ModelImporter importer = AssetImporter.GetAtPath(assetPath) as ModelImporter;
        if (null == importer) return;
        _enableDelete = true;
        _needWaiting = true;

        importer.importMaterials = true;
        importer.importMaterials = false;
        AssetDatabase.ImportAsset(assetPath);
    }

    private void OnPostprocessModel(GameObject model)
    {
        if (null == model) return;

        if (!_enableDelete) return;
        _enableDelete = false;

        Renderer[] renders = model.GetComponentsInParent<Renderer>();
        if (null == renders) return;
        foreach (Renderer render in renders)
        {
            render.sharedMaterials = new Material[render.sharedMaterials.Length];
        }
        _needWaiting = false;
    }
}

使用代碼:

[MenuItem("Assets/Wal Editor/刪除選中模型的材質(zhì)")]
static void DelSelectedModelMat()
{
    Object[] objs = Selection.GetFiltered(typeof (Object), SelectionMode.DeepAssets);
    if(null == objs) return;
    EditorCoroutine.Start(DelModelMats(objs));
}

有幾個地方需要注意:
1.代碼方式修改FBX實際改變的是Unity緩存(Library/metadata)的內(nèi)容,因此它不能被版控管理重罪。這個腳本要在發(fā)布機上執(zhí)行樱哼。
2.這里的處理,在執(zhí)行【右鍵 - Reimport】操作后會恢復(fù)原樣剿配。
3.批處理函數(shù)要用協(xié)程的方式執(zhí)行搅幅,可以參考上一篇文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呼胚,隨后出現(xiàn)的幾起案子茄唐,更是在濱河造成了極大的恐慌,老刑警劉巖蝇更,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沪编,死亡現(xiàn)場離奇詭異,居然都是意外死亡年扩,警方通過查閱死者的電腦和手機蚁廓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厨幻,“玉大人相嵌,你說我怎么就攤上這事】龃啵” “怎么了平绩?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漠另。 經(jīng)常有香客問我,道長跃赚,這世上最難降的妖魔是什么笆搓? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任性湿,我火速辦了婚禮,結(jié)果婚禮上满败,老公的妹妹穿的比我還像新娘肤频。我一直安慰自己,他們只是感情好算墨,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布宵荒。 她就那樣靜靜地躺著,像睡著了一般净嘀。 火紅的嫁衣襯著肌膚如雪报咳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天挖藏,我揣著相機與錄音暑刃,去河邊找鬼。 笑死膜眠,一個胖子當(dāng)著我的面吹牛岩臣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宵膨,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼架谎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辟躏?” 一聲冷哼從身側(cè)響起谷扣,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸿脓,沒想到半個月后抑钟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡野哭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年在塔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拨黔。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛔溃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篱蝇,到底是詐尸還是另有隱情贺待,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布零截,位于F島的核電站麸塞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涧衙。R本人自食惡果不足惜哪工,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一奥此、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雁比,春花似錦稚虎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茴她,卻和暖如春寻拂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背败京。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工兜喻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赡麦。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓朴皆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泛粹。 傳聞我的和親對象是個殘疾皇子遂铡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容