Unity Prefab導入檢查

 unity製作prefab的時候,有的時候可能需要hold住導入操作來做一點事情,這裏提供兩種思路來處理;

下面這個例子,是爲了設置Animator的cullingmode;

方案一:修改prefab的文本

而修改了.prefab的文件,然後保存;

using UnityEngine;
using UnityEditor;
using System.Text.RegularExpressions;
using System.IO;

class MyAllPostprocessor : AssetPostprocessor
{
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        foreach (string str in importedAssets)
        {
            Regex prefabSuffix = new Regex(".prefab$");
            string absolutePath = Application.dataPath + str.Replace("Assets", "");
            if (prefabSuffix.IsMatch(str)){
                ResetTxt(absolutePath);
            }
        }
    }
    static void ResetTxt(string path){
        StreamReader sr = new StreamReader(path);
        string str = sr.ReadToEnd();
        sr.Close();
        string pattern = @"m_CullingMode: \d";
        Regex prefabSuffix = new Regex(pattern);
        if(prefabSuffix.IsMatch(str)){
            str = prefabSuffix.Replace(str, "m_CullingMode: 2");
        }
        StreamWriter sw = new StreamWriter(path, false);
        sw.WriteLine(str);
        sw.Close();
    }
}

方案二:使用PrefabUtility

using UnityEngine;
using UnityEditor;
using System.Text.RegularExpressions;
using System.IO;

class MyAllPostprocessor : AssetPostprocessor
{
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        foreach (string str in importedAssets)
        {
            Regex prefabSuffix = new Regex(".prefab$");
            string absolutePath = Application.dataPath + str.Replace("Assets", "");
            if (prefabSuffix.IsMatch(str)){
                ResetAnimator(str);
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    static void ResetAnimator(string path){
        GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
        bool hit = false;
        var newPrefab = PrefabUtility.InstantiatePrefab(obj) as GameObject;
        Animator[] animators = newPrefab.GetComponentsInChildren<Animator>(true);
        for (int i = 0; i < animators.Length; i++)
        {
            var animator = animators[i];
            if(animator.cullingMode != AnimatorCullingMode.CullCompletely)
            {
                hit = true;
                animator.cullingMode = AnimatorCullingMode.CullCompletely;
            }
        }
        if (hit)
        {
            PrefabUtility.SaveAsPrefabAsset(newPrefab, path);
            GameObject.DestroyImmediate(newPrefab);
            return;
        }
        GameObject.DestroyImmediate(newPrefab);
        return;
    }
}

擴展:使用MenuItem對選中prefab進行操作

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

public class ArtPrefabMenu
{
    [MenuItem("Tools/設置CullingMode爲CullingCompletely")]
    public static void SetPrefabCullingMode()
    {
        List<string> prefabPathList = new List<string>();
        for(int i = 0; i < Selection.assetGUIDs.Length; i++){
            string path = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[i]);
            prefabPathList.Add(path);
        }
        ArtToolUtil.CheckFuncWithProgress<UnityEngine.GameObject>(prefabPathList.ToArray(), "檢查Prefab的Animator", (string path, UnityEngine.GameObject rootGo) =>
        {
            bool hit = false;
            var newPrefab = PrefabUtility.InstantiatePrefab(rootGo) as GameObject;
            Animator[] animators = newPrefab.GetComponentsInChildren<Animator>(true);
            for (int i = 0; i < animators.Length; i++)
            {
                var animator = animators[i];
                if(animator.cullingMode != AnimatorCullingMode.CullCompletely)
                {
                    hit = true;
                    animator.cullingMode = AnimatorCullingMode.CullCompletely;
                }
            }
            if (hit)
            {
                PrefabUtility.SaveAsPrefabAsset(newPrefab, path);
                GameObject.DestroyImmediate(newPrefab);
                return string.Format("path==>{0}", path);
            }
            GameObject.DestroyImmediate(newPrefab);
            return null;
        });
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章