去掉無用節點

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditorInternal;

    // 美術在導出模型時,有很多掛點是沒有用的。但有些掛點卻是有用的,跟美術溝通,有用掛點的名字。
    // 再使用該腳本進行一健清理
    public class BatchAnimatorOptimize
    {
        // 指定要檢查的文件夾
        private static string[] checkDirs = {
            //"Assets/Game/Actors",
            //"Assets/Game/Actors/Wing/8001",
        //"Assets/Game/Actors/Mount/7004"
        };

        private static string[] searchPatterns = new string[] {
            "buff_.*",
            "hurt_.*",
            "_.*point",
            "ui",
            "guadian",
        };


        [MenuItem("自定義工具/優化動畫(去掉無用節點)")]
        public static void Process()
        {
            Debug.Log("開始批量處理");
            string[] guids = AssetDatabase.FindAssets("t:prefab", checkDirs);
            foreach (var guid in guids)
            {
                string path = AssetDatabase.GUIDToAssetPath(guid);
                GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                if (null == prefab.GetComponent<Animator>()
                    || null == prefab.GetComponentInChildren<SkinnedMeshRenderer>())
                {
                    continue;
                }

                if (null != prefab.GetComponent<Animator>()
                    && null != prefab.transform.Find("GameObject")
                    && prefab.transform.childCount <= 3)
                {
                    Debug.Log("處理有BuG的:" + path);
                   // ProcessForBug(prefab);
                }
                else
                {
                    Debug.Log("處理無BuG的:" + path);
                    ProcessCollect(prefab);
                }
            }

            AssetDatabase.SaveAssets();

            Debug.Log("處理完成");
        }

        private static void ProcessForBug(GameObject prefab)
        {
            GameObject prefab_obj = GameObject.Instantiate(prefab);
            GameObject temp_gameobj = prefab_obj.transform.Find("GameObject").gameObject;
            temp_gameobj.transform.SetParent(prefab_obj.transform.parent, true);

            Animator animator = prefab_obj.GetComponent<Animator>();
            ComponentUtility.CopyComponent(animator);
            ComponentUtility.PasteComponentAsNew(temp_gameobj);
            GameObject.DestroyImmediate(animator);

            string[] exposed_transforms = new string[] { };
            SearchExposed(temp_gameobj.transform, ref exposed_transforms);

            if (exposed_transforms.Length > 0)
            {
                AnimatorUtility.OptimizeTransformHierarchy(temp_gameobj, exposed_transforms);
            }

            temp_gameobj.transform.SetParent(prefab_obj.transform, true);

            PrefabUtility.ReplacePrefab(prefab_obj, prefab);
            GameObject.DestroyImmediate(prefab_obj);
        }

        private static void ProcessCollect(GameObject prefab)
        {
            string[] exposed_transforms = new string[] { };
            SearchExposed(prefab.transform, ref exposed_transforms);

            if (exposed_transforms.Length > 0)
            {
                AnimatorUtility.OptimizeTransformHierarchy(prefab, exposed_transforms);
            }

            PrefabUtility.ResetToPrefabState(prefab);
            PrefabUtility.SetPropertyModifications(prefab, new PropertyModification[] { });
        }

        private static void SearchExposed(Transform root, ref string[] exposedTransforms)
        {
            var pathStack = new List<string>();
            for (int i = 0; i < searchPatterns.Length; ++i)
            {
                if (string.IsNullOrEmpty(searchPatterns[i]))
                {
                    continue;
                }

                var regex = new Regex(searchPatterns[i]);
                SearchExposed(pathStack, root, regex, ref exposedTransforms);
                pathStack.Clear();
            }
        }

        private static void SearchExposed(List<string> pathStack, Transform transform, System.Text.RegularExpressions.Regex regex, ref string[] exposedTransforms)
        {
            pathStack.Add(transform.name);
            var pathBuilder = new StringBuilder();
            for (int i = 0; i < pathStack.Count; ++i)
            {
                pathBuilder.Append(pathStack[i]);
                if (i < pathStack.Count - 1)
                {
                    pathBuilder.Append('/');
                }
            }

            var path = pathBuilder.ToString();
            if (regex.IsMatch(path))
            {
                AddExposedTransform(path, ref exposedTransforms);
            }

            foreach (Transform child in transform)
            {
                SearchExposed(pathStack, child, regex, ref exposedTransforms);
            }

            pathStack.RemoveAt(pathStack.Count - 1);
        }

        private static void AddExposedTransform(string value, ref string[] exposedTransforms)
        {
            foreach (var stringValue in exposedTransforms)
            {
                if (stringValue == value)
                {
                    return;
                }
            }

            ArrayUtility.Add(ref exposedTransforms, value);
        }
    }
 

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