obsidian/笔记文件/2.笔记/EmotionEditor.md
2025-03-26 00:02:56 +08:00

34 KiB
Raw Blame History

#unity/白日梦/代码缓存

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using LightUtility;
using ResourcesModule.LMNA;
using UnityEngine;
using UnityEditor;
using UtilityModule.EditorExpand;
using eAssetFunctionType = ResourcesModule.LMNA.eAssetFunctionType;
using DMM.EditorExpand.ToolEditor;
using SmartResourceRuleTool;


public class EmotionEditor : EditorWindow
{
    
    
    private static EmotionEditor m_Window;
    private static string m_InGameEmotionPath = "Assets/ResourcesRaw/Mainland/Tables/Client/IngameEmotion.csv";

    private const string emotionConfig = "/BundleResources/CommonRegion/Common/Skins/Emotions/";

    private string emotions = "";

    private Dictionary<string,string> ResourcesRawDic = new Dictionary<string, string>
    {
        ["lob_"] = "/ResourcesRaw/CommonRegion/OutsideGame/Skins/Emotions/",
        ["ing_"] = "/ResourcesRaw/CommonRegion/InGame/Skins/Emotions/"
    };
    
    private Dictionary<string,string> BundleResourcesDic = new Dictionary<string, string>
    {
        ["com_"] = "Assets/BundleResources/CommonRegion/Common/Skins/Emotions/",
        ["lob_"] = "Assets/BundleResources/CommonRegion/OutsideGame/Skins/Emotions/",
        ["ing_"] = "Assets/BundleResources/CommonRegion/InGame/Skins/Emotions/"
    };
    
    private Dictionary<string,bool> fbxChildDic = new Dictionary<string, bool>();
    private Dictionary<Transform,Transform> sonAndParentDic = new Dictionary<Transform, Transform>();
    private static Dictionary<int,EmotionTable> mEmotionDic = new Dictionary<int, EmotionTable>();
    
    //EmotionTable
    private static int mTypeIndex = 0;
    private static int mConfigIndex = 0;
    private static int mLanNameIndex = 0;



    // 界面相关
    Color m_BlueColor = new Color(129 / 255f, 209 / 255f, 248 / 255f, 1);
    Color m_PinkColor = new Color(253 / 255f, 184 / 255f, 225 / 255f, 1);
    Color m_RedColor = new Color(233 / 255f, 74 / 255f, 110 / 255f, 1);
    Color m_PurpColor = new Color(125 / 255f, 128 / 255f, 227 / 255f, 1);
    float m_RowHeight = 20f;
    int m_RowFontSize = 12;
    GUIStyle m_MainHeaderStyle;
    GUIStyle m_SubHeaderStyle;
    GUIStyle m_ButtonStyle;
    GUIStyle m_TipsStyle;
    GUIStyle m_ErrorTipsStyle;
    GUIStyle m_LabelStyle;
    GUIStyle m_TagLabelStyle;
    GUIStyle m_ParamsLabelStyle;

    
    private List<Dictionary<string,object>> AllFileList = new List<Dictionary<string, object>>();
    
    
    List<FileInfo> nodeList = new List<FileInfo>();
    Dictionary<FileInfo,int> alreadyUseNodeList = new Dictionary<FileInfo,int>();
    List<bool> ChooseList = new List<bool>();
    private Dictionary<int,string> fixFrontNameList = new Dictionary<int, string>();
    
    private bool isChoose;
    private bool isSelected;
    private bool isSuccess;

    private bool isChooseAll;
    private bool isChooseAllTemp;


    private GameObject m_FbxSenceObject;
    
    private eAssetSceneType currentAssetSceneType = eAssetSceneType.Unknown;
    private eAssetLodLevel currentAssetLodLevel = eAssetLodLevel.None;
    
    private Dictionary<string,eAssetLodLevel> levelDic = new Dictionary<string, eAssetLodLevel>
    {
        ["lv0"] = eAssetLodLevel.Lv0,
        ["lv1"] = eAssetLodLevel.Lv1,
        ["lv2"] = eAssetLodLevel.Lv2,
        ["lv3"] = eAssetLodLevel.Lv3,
        ["lv4"] = eAssetLodLevel.Lv4
    };

    private Dictionary<string, eAssetSceneType> sceneDic = new Dictionary<string, eAssetSceneType>
    {
        ["lob"] = eAssetSceneType.Lobby,
        ["ing"] = eAssetSceneType.InGame
    };

    void InitParams()
    {
        if (emotions.Length <= 0)
        {
            emotions = File.ReadAllText(m_InGameEmotionPath);
            ParseCSV(emotions);
        }
    }

    /// <summary>
    /// 创建文件夹路径
    /// </summary>
    /// <param name="path"></param>
    void CreateDirectory(string path)
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }

    void ParseCSV(string m_InGameEmotionPath)
    {
        mEmotionDic.Clear();
        string[] lines = m_InGameEmotionPath.Split(new [] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
        
        string[] paramCells = lines[1].Split(','); // 用第二行来获得字段 index
        for (int i = 0; i < paramCells.Length; ++i)
        {
            switch (paramCells[i])
            {
                case "Config":
                    mConfigIndex = i;
                    break;
                case "Lan_Name":
                    mLanNameIndex = i;
                    break;
                case "Type":
                    mTypeIndex = i;
                    break;
            }
        }

        int currentSec = 2;//跳过前两行的title与fields文字
        int configNumber = 0;
        int type = 0;
        string LanName = "";

        while (currentSec < lines.Length)
        {
            string[] cells = lines[currentSec].Split(',');
            LanName = "";

            if (cells[mConfigIndex].Length > 0)
            {
                configNumber = int.Parse(cells[mConfigIndex]);
                type = int.Parse(cells[mTypeIndex]);

                if (cells[mLanNameIndex].Length > 0)
                {
                    LanName = cells[mLanNameIndex];
                }
                
                EmotionTable EmotionFields = new EmotionTable
                {
                    type = type
                };
                
                    
                mEmotionDic[configNumber] = EmotionFields;
                
            }
            
            ++currentSec;
        }
        
    }

    void InitStyles()
    {
        if (m_MainHeaderStyle == null)
        {
            m_MainHeaderStyle = new GUIStyle(GUI.skin.label);
            m_MainHeaderStyle.fontSize = 20;
            m_MainHeaderStyle.fontStyle = FontStyle.Bold;
            m_MainHeaderStyle.normal.textColor = m_BlueColor;
        }

        if (m_SubHeaderStyle == null)
        {
            m_SubHeaderStyle = new GUIStyle(GUI.skin.label);
            m_SubHeaderStyle.fontSize = 14;
            m_SubHeaderStyle.fontStyle = FontStyle.Bold;
            m_SubHeaderStyle.normal.textColor = m_BlueColor;
        }

        if (m_ButtonStyle == null)
        {
            m_ButtonStyle = new GUIStyle(GUI.skin.button);
            m_ButtonStyle.fontSize = 14;
            m_ButtonStyle.richText = true;
        }

        if (m_TipsStyle == null)
        {
            m_TipsStyle = new GUIStyle(GUI.skin.label);
            m_TipsStyle.normal.textColor = m_PinkColor;
            m_TipsStyle.fontSize = m_RowFontSize;
        }

        if (m_ErrorTipsStyle == null)
        {
            m_ErrorTipsStyle = new GUIStyle(GUI.skin.label);
            m_ErrorTipsStyle.normal.textColor = m_RedColor;
            m_ErrorTipsStyle.fontSize = m_RowFontSize;
        }

        if (m_LabelStyle == null)
        {
            m_LabelStyle = new GUIStyle(GUI.skin.label);
            m_LabelStyle.normal.textColor = m_BlueColor;
            m_LabelStyle.fontSize = 18;
        }

        if (m_TagLabelStyle == null)
        {
            m_TagLabelStyle = new GUIStyle(GUI.skin.label);
            m_TagLabelStyle.normal.textColor = m_PinkColor;
            m_TagLabelStyle.fontSize = 16;
        }

        if (m_ParamsLabelStyle == null)
        {
            m_ParamsLabelStyle = new GUIStyle(GUI.skin.label);
            m_ParamsLabelStyle.normal.textColor = m_PurpColor;
            m_ParamsLabelStyle.fontSize = 13;
        }

        
    }


    [MenuItem("美术工具/表情动作导入",false,2)]
    static void ShowWindow()
    {
        if (m_Window == null)
        {
            m_Window = (EmotionEditor)GetWindow(typeof(EmotionEditor), true, "EmotionEditor");
            m_Window.Show();
        }
        else
        {
            m_Window.Close();
            m_Window = null;
        }
    }

    /// <summary>
    /// 修复前缀
    /// </summary>
    /// <param name="index"></param>
    private string FixFront(string name,int index)
    {
        if (name.Contains("&"))
        {
            fixFrontNameList[index] = "mdl";
        }
        else
        {
            fixFrontNameList[index] = "mdl&";
        }

        return fixFrontNameList[index];
    }

    bool checkName(string name,int index)
    {
        fixFrontNameList.Add(index,"");
        string[] nameList_First = name.Split('&');
        
        //缺少前缀的情况,修复前缀
        if (nameList_First.Length == 1)
        {
            if (!name.Contains("mdl"))
            {
                name = FixFront(name, index) + name;
                nameList_First = name.Split('&');
            }
            else
            {
                ShowTipsLog($"{name}模型资源命名不正确,特殊字符有问题");
                return false;
            }
        }
        else if (nameList_First.Length > 2)
        {
            ShowTipsLog($"{name}模型资源命名不正确,特殊字符有问题");
            return false;
            
        }
        else
        {
            //存在前缀的情况,修复前缀
            if (nameList_First[0].Length == 0)
            {
                name = FixFront(name, index) + name;
                nameList_First = name.Split('&');
            }
        }

        string[] nameList_Second = nameList_First[1].Split('@');
        if (nameList_Second.Length != 2 || nameList_Second[0].Length == 0)
        {
            ShowTipsLog($"{name}模型资源命名不正确,特殊字符有问题");
            return false;
        }


        if (!(nameList_Second[0].Contains("lob_") || nameList_Second[0].Contains("ing_")))
        {
            ShowTipsLog($"{name}模型资源命名不正确,缺少局内外标识");
            return false;
        }

        string[] nameList_Third = nameList_Second[1].Split('_');
        string param = Path.GetFileNameWithoutExtension(nameList_Third[0]);
        int skinNumber = 0;

        if (!int.TryParse(param,out skinNumber))
        {
            ShowTipsLog($"{name}模型编号不是数字,请检查资源命名");
            return false;
        }
        
        return true;
    }

    private void ScrollViewShow(List<FileInfo> mainList)
    {

        for (int o = 0; o < ChooseList.Count; o++)
        {
            EditorGUILayout.BeginHorizontal();
            
            EditorGUILayout.LabelField(fixFrontNameList[o] + mainList[o].Name);
            EditorGUILayout.Space();
            ChooseList[o] = EditorGUILayout.Toggle(ChooseList[o]);
            
            
            
            EditorGUILayout.EndHorizontal();
        }
        
        // for (int i = 0; i < mainList.Count; i++)
        // {
        //     EditorGUILayout.BeginHorizontal();
        //         
        //     GUILayout.Label(mainList[i].Name);
        //
        //     if (GUILayout.Button(txt,m_ButtonStyle))
        //     {
        //         if (!checkName(mainList[i].Name))
        //         {
        //             return;
        //         }
        //         notMainList.Add(mainList[i]);
        //         mainList.RemoveAt(i);
        //     }
        //
        //         
        //     EditorGUILayout.EndHorizontal();
        // }
    }
    
    

    Vector2 _scrollPos;

    private void DrawList()
    {
        EditorGUILayout.Space();

        EditorGUILayout.BeginVertical();

        EditorGUILayout.LabelField("文件夹里包含的FBX文件列表选择");


        isChooseAll = EditorGUILayout.Toggle("是否全选", isChooseAll);


        EditorGUILayout.Space();

        _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, false, true);


        ScrollViewShow(nodeList);
        
        if (isChooseAll != isChooseAllTemp)
        {
            isChooseAllTemp = isChooseAll;

            for (int i = 0; i < ChooseList.Count; i++)
            {
                ChooseList[i] = isChooseAll;
            }
            
            EditorPrefs.SetBool("EmotionActionAllChoose", isChooseAll);
        }

        
        
        EditorGUILayout.EndScrollView();
        
        EditorGUILayout.Space();
        
        EditorGUILayout.EndVertical();

    }
    
    void OnGUI()
    {
        InitParams();
        InitStyles();
        
        EditorGUILayout.Space();

        if (isChoose == false)
        {
            if (GUILayout.Button("选表情动作所在文件夹",m_ButtonStyle,GUILayout.Width(150),GUILayout.Height(m_RowHeight)))
            {
                isSuccess = OnClickLoadButton();

                if (EditorPrefs.HasKey("EmotionActionAllChoose"))
                {
                    isChooseAll = EditorPrefs.GetBool("EmotionActionAllChoose");
                    isChooseAllTemp = false;
                }
            }
        }
        else
        {

            EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button("导入", m_ButtonStyle, GUILayout.Width(150), GUILayout.Height(m_RowHeight)))
            {

                for (int i = 0; i < ChooseList.Count; i++)
                {
                    if (ChooseList[i])
                    {
                        alreadyUseNodeList.Add(nodeList[i],i);
                    }
                }
                
                OnClickCreateButton(isSuccess);
            }

            
            EditorGUILayout.EndHorizontal();
            
            DrawList();
            
        }



    }
    
    void OnClickCreateButton(bool isSuccess = true)
    {
        if (isSuccess == false)
        {
            return;
        }

        if (alreadyUseNodeList.Count <= 0)
        {
            ShowTipsLog("未选择fbx文件");
            return;
        }


        foreach (KeyValuePair<FileInfo,int> keyValuePair in alreadyUseNodeList)
        {
            
            ImportResource(keyValuePair.Key,keyValuePair.Value);
        }

        // for (int j = 0; j < alreadyUseNodeList.Count; j++)
        // {
        // }

        AssetDatabase.Refresh();
        
        for (int i = 0; i < AllFileList.Count; i++)
        {
           
            
            string belongPath = AllFileList[i]["belongPath"] as string;
            string modelParam = AllFileList[i]["modelParam"] as string;
            string style = AllFileList[i]["style"] as string;
            string inOut = AllFileList[i]["inOut"] as string;
            string AssetPath = AllFileList[i]["AssetPath"] as string;
            string animPath = "";
            

            int emotionKey = int.Parse(modelParam);
            //判断表情动作配表是否存在该模型id并且对应的类型是否为动作
            if (mEmotionDic.ContainsKey(emotionKey) && mEmotionDic[emotionKey].type == 1)
            {
                //如果是局内的模型,需要特殊处理一下
                if (inOut == "ing_" && style == "model")
                {
                    EmotionEditorUtil.FixHumanoidAnimationParams(AssetPath);
                }

                //从FBX中分离出animationClip并且放进正确的路径
                animPath = SeparateAnimationClipFromFBXTool.TrySperateAnimationClipFromFBXInRightPath(AssetPath);
                
                if (style == "prop")
                {
                    GameObject fbxObject = GetFbxGameObject(AllFileList[i]["fbxPath"] as string);
                    CreatePropPrefab(ref fbxObject,AllFileList[i]);
                }
                //表情动作,才生成对应的预制体,模型动作本身,不生成预制体
                // if (style == "model") 
                // {
                //     animPath = BundleResourcesDic[inOut] + belongPath + "/Animations/" + @"ani&" + inOut + belongPath +
                //                @"@" + modelParam + ".anim";
                // }
                // else if (style == "prop")
                // {
                //     GameObject fbxObject = GetFbxGameObject(AllFileList[i]["fbxPath"] as string);
                //     CreatePropPrefab(ref fbxObject,AllFileList[i]);
                // }
                
                string configPath = BundleResourcesDic["com_"] + belongPath + "/Configs/" + @"sco&" + modelParam +
                                    ".asset";
                // List<string> allConfigPaths = EditorUtilities.SearchFiles(dir, new[] {$"sco&{modelParam}*.asset"});
                IngameEmotionConfig config =
                    AssetDatabase.LoadAssetAtPath<IngameEmotionConfig>(EditorPathUtil.GetAssetPath(configPath));
                
                if (config == null)
                {
                    // ShowTipsLog($"找不到对应的sco&{modelParam}配置文件,程序正在自动生成一个");
                    CreateDirectory(BundleResourcesDic["com_"] + belongPath + "/Configs/");
                    configPath = BundleResourcesDic["com_"] + belongPath + "/Configs/" + @"sco&" + modelParam +
                                        ".asset";

                    IngameEmotionConfig newSetting = CreateInstance<IngameEmotionConfig>();
                    AssetDatabase.CreateAsset(newSetting,configPath);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();
                    
                    config = AssetDatabase.LoadAssetAtPath<IngameEmotionConfig>(EditorPathUtil.GetAssetPath(configPath));
                }
                
                EmotionEditorUtil.RefreshEmotionConfig(config,animPath);
                Selection.activeObject = config;
                EditorGUIUtility.PingObject(config);
                
            }
            else
            {
                ShowTipsLog($"该{modelParam}编号的模型,不匹配策划配表内容,请跟对应的策划确认");
            }

        }

        
        ClearGC();

    }

    bool OnClickLoadButton()
    {
        bool success = true;
        string defaultFolder = PlayerPrefs.GetString("EmotionActionFolder", "");
        string folder = EditorUtility.OpenFolderPanel("Select Versions Folder", defaultFolder, "");
        if (string.IsNullOrEmpty(folder))
        {
            return false;
        }

        PlayerPrefs.SetString("EmotionActionFolder", folder);
        DirectoryInfo diretion = new DirectoryInfo(folder);

        FileInfo[] fbxFiles = diretion.GetFiles("*.fbx", SearchOption.AllDirectories);
        
        if (fbxFiles.Length == 0)
        {
            NamingChecker.PopupErrorMessage("未检测到有fbx导入");
            return false;
        }

        ClearGC();

        

        for (int i = 0; i < fbxFiles.Length; i++)
        {

            if (!checkName(fbxFiles[i].Name,i))
            {
                return false;
            }
            ChooseList.Add(false);
            nodeList.Add(fbxFiles[i]);

            // CheckName(fbxFiles[i]);

        }
        
        isChoose = true;
        // AssetDatabase.Refresh();
        

        return success;
    }


    GameObject GetFbxGameObject(string path)
    {
        string relativePath = NamingChecker.GetRelativePath(path);
        Transform fbxTrans = AssetDatabase.LoadAssetAtPath(relativePath, typeof(Transform)) as Transform;
        if (m_FbxSenceObject != null) // 不要重复生成,关闭的时候清不掉
        {
            DestroyImmediate(m_FbxSenceObject.gameObject);
        }
        m_FbxSenceObject = Instantiate(fbxTrans).gameObject;
        return m_FbxSenceObject;
    }
    
    /// <summary>
    /// 获取fbx对应的prefab名字
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    string GetPrefabName(string name)
    {
        string[] nameList = name.Split('&');
        eAssetLodLevel level = eAssetLodLevel.None;
        string finalName = String.Empty;

        foreach (KeyValuePair<string,eAssetLodLevel> keyValuePair in levelDic)
        {
            if (nameList[0].Contains(keyValuePair.Key))
            {
                level = keyValuePair.Value;
                currentAssetLodLevel = level;
                break;
            }
        }

        foreach (KeyValuePair<string,eAssetSceneType> keyValuePair in sceneDic)
        {
            if (nameList[1].Contains(keyValuePair.Key))
            {
                currentAssetSceneType = keyValuePair.Value;
            }
        }
            


        if (nameList.Length == 2 )
        {
            string[] logicNamelist = nameList[1].Split('_');
            if (logicNamelist.Length > 4)
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Clear();

                for (int i = 0; i < 3; i++)
                {
                    stringBuilder.Append(logicNamelist[i] + "_");
                }

                stringBuilder.Append(logicNamelist[3]);
                    
                    

                string prefabName = stringBuilder.ToString();

                stringBuilder.Clear();
                finalName = LMNAResMapUtil.AssembleAssetName(prefabName, eAssetFunctionType.GameObject,
                    level);

            }
        }

        return finalName;
    }

    private string currentName = "";
    private Transform currentTrans;
    void CreatePropPrefab(ref GameObject fbxGameObject,Dictionary<string,object> node)
    {
        string prefabName = "";
        string belongPath = node["belongPath"] as string;
        string inOut = node["inOut"] as string;
        string AssetPath = node["AssetPath"] as string;
        string finalPath = BundleResourcesDic[inOut] + belongPath + "/";
        string fbxPath = node["fbxPath"] as string; 
        string Prop_prefabPath = "";
        
        prefabName = fbxGameObject.name.Split('(')[0];
        eAssetFunctionType functionType = eAssetFunctionType.Unknown;
        eAssetLodLevel lodLevel = eAssetLodLevel.None;
        eAssetSceneType sceneType = eAssetSceneType.Unknown;
        LMNAResMapUtil.ParseAssetName(Path.GetFileNameWithoutExtension(prefabName), ref functionType, ref lodLevel, ref sceneType, out prefabName);
        prefabName = LMNAResMapUtil.AssembleAssetName(prefabName, eAssetFunctionType.GameObject, lodLevel);
        // realPrefabName = GetPrefabName(prefabName);
        prefabName = DropPostfix(prefabName);
        
        if (!Directory.Exists(finalPath))
        {
            ShowTipsLog($"该{belongPath}路径不存在,请检查命名是否正确");
            DestroyImmediate(fbxGameObject.gameObject);
        }




        string PropPrefabsPath = finalPath + "PropPrefabs/";

        if (!Directory.Exists(PropPrefabsPath))
        {
            Directory.CreateDirectory(PropPrefabsPath);
        }

        //表情动作模型和动画
        if (AssetPath.Contains("_prop"))
        {
            ModelImporter mi = AssetImporter.GetAtPath(AssetPath) as ModelImporter;
            string animPath = String.Empty;
            if (mi != null)
            {
                mi.animationType = ModelImporterAnimationType.Legacy;
                mi.SaveAndReimport();
                animPath = EmotionEditorUtil.CreatePropAnimEvent(AssetPath, mi);
            }
            
            GameObject model = AssetDatabase.LoadAssetAtPath<GameObject>(NamingChecker.GetRelativePath(fbxPath));
            
            UnityEngine.Profiling.Profiler.BeginSample($"Instantiate {model}");
            UnityEngine.Profiling.Profiler.EndSample();
            GameObject prefabInst = Instantiate(model);
            
            
            Animation animComponent = prefabInst.GetComponent<Animation>();
            if (animComponent != null)
            {
                animComponent.playAutomatically = true;
                animComponent.cullingType = AnimationCullingType.AlwaysAnimate;
            }
            
            
            Poolable poolComponent = prefabInst.GetComponent<Poolable>();
            if (poolComponent == null)
            {
                prefabInst.AddComponent<Poolable>();
            }
            
            fbxChildDic.Clear();
            sonAndParentDic.Clear();
            
            

            //判断prefab是否已存在
            string prefabPath = PropPrefabsPath + prefabName + ".prefab";
            
            if (File.Exists(prefabPath))
            {
                
                GameObject alreadyPrefab =
                    Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath));
            
                GetAllChild(prefabInst.transform, "", fbxChildDic);
                CheckAllChild(alreadyPrefab.transform, "", prefabInst);

                foreach (KeyValuePair<Transform,Transform> keyValuePair in sonAndParentDic)
                {
                    keyValuePair.Key.parent = keyValuePair.Value;
                }
                
                sonAndParentDic.Clear();
                
                //判断一下自身是否有挂载skinMeshrender
                if (alreadyPrefab.GetComponent<SkinnedMeshRenderer>() != null)
                {
                    
                    List<Material> materials = new List<Material>(alreadyPrefab.GetComponent<SkinnedMeshRenderer>().sharedMaterials);
                    if (prefabInst.GetComponent<SkinnedMeshRenderer>() == null)
                    {
                        prefabInst.AddComponent<SkinnedMeshRenderer>();
                    }
                    
                    prefabInst.GetComponent<SkinnedMeshRenderer>().sharedMaterials = materials.ToArray();
                }
                else if (alreadyPrefab.GetComponent<MeshRenderer>() != null)
                {
                    List<Material> materials = new List<Material>(alreadyPrefab.GetComponent<MeshRenderer>().sharedMaterials);
                    if (prefabInst.GetComponent<MeshRenderer>() == null)
                    {
                        prefabInst.AddComponent<MeshRenderer>();
                    }
                    
                    prefabInst.GetComponent<MeshRenderer>().sharedMaterials = materials.ToArray();
                }
                
                DestroyImmediate(alreadyPrefab.gameObject);   
            }
            
            Prop_prefabPath = PropPrefabsPath + prefabName + ".prefab";
            
            PrefabUtility.SaveAsPrefabAssetAndConnect(prefabInst, Prop_prefabPath, InteractionMode.AutomatedAction);
            AssetDatabase.SaveAssets();
            DestroyImmediate(prefabInst.gameObject);
            AssetDatabase.Refresh();

            if (animPath.Length > 0)
            {
                EmotionEditorUtil.BindAnimPrefab(Prop_prefabPath, animPath);
            }
            
        }
        DestroyImmediate(fbxGameObject.gameObject);
    }
    void GetAllChild(Transform trans, string path,Dictionary<string,bool> dic)
    {
        if (trans.childCount > 0)
        {
            for (int i = 0; i < trans.childCount; i++)
            {
                currentName = path + "/" + trans.GetChild(i).name;
                dic.Add(currentName,true);
                GetAllChild(trans.GetChild(i).transform,currentName,dic);
            }
        }
    }

    void CheckAllChild(Transform trans, string path,GameObject fbx)
    {
        if (trans.childCount > 0)
        {
            for (int i = 0; i < trans.childCount; i++)
            {
                currentName = path + "/" + trans.GetChild(i).name;
                if (fbxChildDic.ContainsKey(currentName))
                {

                    if (trans.GetChild(i).GetComponent<SkinnedMeshRenderer>() != null)
                    {
                        List<Material> materials = new List<Material>(trans.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterials);
                        string[] nameList = currentName.Split('/');
                        List<string> nameInList = new List<string>();
                        for (int j = 0; j < nameList.Length; j++)
                        {
                            if (nameList[j].Length > 0)
                            {
                                nameInList.Add(nameList[j]);
                            }
                        }
                        GetChild(fbx.transform, nameInList, 0);
                        if (currentTrans.GetComponent<SkinnedMeshRenderer>() == null)
                        {
                            currentTrans.gameObject.AddComponent<SkinnedMeshRenderer>();
                        }

                        currentTrans.GetComponent<SkinnedMeshRenderer>().sharedMaterials = materials.ToArray();

                    }
                    else if (trans.GetChild(i).GetComponent<MeshRenderer>() != null)
                    {
                        List<Material> materials = new List<Material>(trans.GetChild(i).GetComponent<MeshRenderer>().sharedMaterials);
                        string[] nameList = currentName.Split('/');
                        List<string> nameInList = new List<string>();
                        for (int j = 0; j < nameList.Length; j++)
                        {
                            if (nameList[j].Length > 0)
                            {
                                nameInList.Add(nameList[j]);
                            }
                        }
                        GetChild(fbx.transform, nameInList, 0);
                        if (currentTrans.GetComponent<MeshRenderer>() == null)
                        {
                            currentTrans.gameObject.AddComponent<MeshRenderer>();
                        }

                        currentTrans.GetComponent<MeshRenderer>().sharedMaterials = materials.ToArray();
                    }
                    
                    CheckAllChild(trans.GetChild(i).transform,currentName,fbx);
                }
                else
                {
                    string[] nameList = path.Split('/');
                    List<string> nameInList = new List<string>();
                    for (int j = 0; j < nameList.Length; j++)
                    {
                        if (nameList[j].Length > 0)
                        {
                            nameInList.Add(nameList[j]);
                        }
                    }
                    GetChild(fbx.transform, nameInList, 0);
                    
                    sonAndParentDic.Add(trans.GetChild(i),currentTrans);
                    // trans.GetChild(i).parent = currentTrans;
                }
            }
        }
    }
    
    void GetChild(Transform fbxTrans, List<string> nameList,int index)
    {
        if (nameList.Count == 0)
        {
            currentTrans = fbxTrans;
            
        }
        else
        {

            if (index == nameList.Count -1)
            {
                for (int j = 0; j < fbxTrans.childCount; j++)
                {
                    if (fbxTrans.GetChild(j).name == nameList[index])
                    {
                        currentTrans = fbxTrans.GetChild(j);
                        return;
                    }
                }
            }
            else
            {
                
                for (int i = 0; i < fbxTrans.childCount; i++)
                {
                    if (fbxTrans.GetChild(i).name == nameList[index])
                    {
                        GetChild(fbxTrans.GetChild(i),nameList,index + 1);
                        break;
                    }
                }
            }
            
        }
    }
    
    string DropPostfix(string name)
    {
        string postfix = NamingChecker.GetPostfix(name);
        bool isValid = NamingChecker.IsValidPostfix(postfix);
        if (isValid)
        {
            return name.Replace("_" + postfix, "").Replace("mdl", "pfb");
        }
        
        
        return name.Replace("mdl", "pfb");
    }

    void ImportResource(FileInfo file,int index)
    {

        string name = fixFrontNameList[index] + file.Name;
        
        // bool isRightName = true;
        
        string style;
        if (name.Contains("_prop"))
        {
            style = "prop";
        }
        else
        {
            style = "model";
        }
        
        string[] nameList_First = name.Split('&');
        string[] nameList_Second = nameList_First[1].Split('@');
        string[] nameList_Third = nameList_Second[1].Split('_');
        
        

        string param = Path.GetFileNameWithoutExtension(nameList_Third[0]);
        int skinNumber = 0;
        
        
        string belongPath = nameList_Second[0].Replace("lob_", "").Replace("ing_", "");

        string frontPath = "";
        string inOut = "";

        if (nameList_Second[0].Contains("lob_"))
        {
            frontPath =  ResourcesRawDic["lob_"];
            inOut = "lob_";
        }
        else if (nameList_Second[0].Contains("ing_"))
        {
            frontPath =  ResourcesRawDic["ing_"];
            inOut = "ing_";
        }


        string fullPath = "";
        string AssetPath = "";

        if (style == "prop")
        {
            fullPath = Application.dataPath + frontPath + belongPath + "/Props/" + param + "/Animations/";
            AssetPath = "Assets" + frontPath + belongPath + "/Props/" + param + "/Animations/" + name;

        }
        else if (style == "model")
        {
            fullPath = Application.dataPath + frontPath + belongPath + "/Animations/";
            AssetPath = "Assets" + frontPath + belongPath + "/Animations/" + name;
        }


        

        if (!Directory.Exists(fullPath))
        {
            Directory.CreateDirectory(fullPath);
        }

        string fbxPath =  fullPath + name;
        
        
        if (File.Exists(fbxPath))
        {
            AssetDatabase.DeleteAsset(AssetPath);
            AssetDatabase.Refresh();
            // File.Delete(fbxPath);
        }

        file.CopyTo(fbxPath);


        AllFileList.Add(OneEmotionAction(name, fbxPath, belongPath, file, inOut, AssetPath, param, style));
        
    }
    

    void ShowTipsLog(string txt)
    {
        EditorUtility.DisplayDialog("提示", txt, "了然");
        
    }

    Dictionary<string, object> OneEmotionAction(string name,string fbxPath,string belongPath,FileInfo file,string inOut,string AssetPath,string modelParam,string style)
    {
        Dictionary<string,object> node = new Dictionary<string, object>
        {
            ["fbxPath"] = fbxPath,
            ["belongPath"] = belongPath,
            ["FileInfo"] = file,
            ["inOut"] = inOut,
            ["AssetPath"] = AssetPath,
            ["modelParam"] = modelParam,
            ["style"] = style
        };
        return node;
    }

    void ClearGC()
    {
        AllFileList.Clear();
        nodeList.Clear();
        alreadyUseNodeList.Clear();
        ChooseList.Clear();
        fixFrontNameList.Clear();
    }
    
    private struct EmotionTable
    {
        public int type;
    }
    
    
}