提取Unity中的fbx文件中的動畫片段您觉。
整體思路是:
將fbx加載后,獲取AnimationClip信息拖吼,然后序列滑到新文件中鳞上。
// 生成新的AnimationClip
? ? ? ? ? ? ? ? ? ? ? ? AnimationClip newClip = new AnimationClip();
? ? ? ? ? ? ? ? ? ? ? ? newClip.frameRate = 25;
? ? ? ? ? ? ? ? ? ? ? ? newClip.name = objs[j].name;
? ? ? ? ? ? ? ? ? ? ? ? // 復制數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? // 方法1:該方法僅設置有效數(shù)據(jù),編輯器相關數(shù)據(jù)不會設置到導出資源中
? ? ? ? ? ? ? ? ? ? ? ? EditorUtility.CopySerialized(objs[j], newClip);
直接上代碼:
public class AnimationExporter : AssetBaseExporter { public class FbxInfo { public string m_AssetPath; public string m_AssetName; // 資源名 public bool m_IsExport; // 是否導出 public bool m_IsCompress; //是否壓縮 } string m_AssetPathPrefix = "Assets/Resources/Models"; // 資源路徑前綴(所有需要導出動畫的fbx以該目錄為根目錄绿贞,不同的模型可以在該目錄下新建子目錄) string m_AssetExportPathPrefix = "Assets/Resources/Pack/Ani"; Listm_AssetList; bool m_IsCompress = true; bool m_IsSelectAll = true; Vector2 m_ScrollPos = Vector2.zero; protected override string m_AssetFilter { get { return "t:model"; } } public override string m_ActionResultFileName { get { return "AnimExportResult.txt"; } } public override void Init() { m_ExportResultDict = new Dictionary(); } public override void Draw() { if (m_AssetList == null) { GUI.contentColor = Color.red; EditorGUILayout.TextArea("請選擇資源目錄或者某個導出資源"); GUI.contentColor = Color.white; return; } if (GUILayout.Button("一鍵全選/一鍵取消全選", GUILayout.Height(50))) { m_IsSelectAll = !m_IsSelectAll; for (int idx = 0; idx < m_AssetList.Count; ++idx) { FbxInfo fbxInfo = m_AssetList[idx]; fbxInfo.m_IsExport = m_IsSelectAll; fbxInfo.m_IsCompress = m_IsSelectAll; } } m_ScrollPos = EditorGUILayout.BeginScrollView(m_ScrollPos, false, false); for (int idx = 0; idx < m_AssetList.Count; ++idx) { FbxInfo fbxInfo = m_AssetList[idx]; fbxInfo.m_IsExport = EditorGUILayout.BeginToggleGroup("勾選", fbxInfo.m_IsExport); // 組開始 EditorGUILayout.TextField(fbxInfo.m_AssetName,GUILayout.Width(500)); EditorGUILayout.EndToggleGroup(); // 組結(jié)束 fbxInfo.m_IsCompress = EditorGUILayout.BeginToggleGroup("勾選", fbxInfo.m_IsCompress); // 組開始 EditorGUILayout.TextField("是否壓縮", GUILayout.Width(500)); EditorGUILayout.EndToggleGroup(); // 組結(jié)束 } EditorGUILayout.EndScrollView(); } public override void PreAction() { base.PreAction(); AnimationModelCompresser.GetInstance().Init(); CompressAnimationExcludeInfoMgr.GetInstance().Init(); } public override void DoAction(string resPath, bool isPath) { if (isPath) { for (int idx = 0; idx < m_AssetList.Count; ++idx) { if (m_AssetList[idx].m_IsExport) { m_IsCompress = m_AssetList[idx].m_IsCompress; DoAction(m_AssetList[idx].m_AssetPath); } } AssetDatabase.Refresh(); } else { base.DoAction(resPath, isPath); } } protected override void DoAction(string assetPath) { if (!assetPath.Contains(m_AssetPathPrefix)) return; Object obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)); if (obj == null) return; if (PrefabUtility.GetPrefabType(obj) == PrefabType.ModelPrefab) { // 創(chuàng)建導出目錄 string exportPath = assetPath.Replace(m_AssetPathPrefix, m_AssetExportPathPrefix); exportPath = Application.dataPath.Replace("Assets", exportPath); exportPath = exportPath.Substring(0, exportPath.LastIndexOf("/") + 1); EditorBasePanel.CheckTargetPath(exportPath); GameObject gameObj = GameObject.Instantiate(obj) as GameObject; if (gameObj.GetComponent() == null) { GameObject.DestroyImmediate(gameObj); return; } gameObj.GetComponent().clip = null; if (m_IsCompress) { DictionaryerrorDic = new Dictionary(); AnimationModelCompresser.IsCollectErrorInfo = true; if (AnimationModelCompresser.GetInstance().CompressAnimationModel(assetPath, out errorDic) && errorDic.Count > 0) { // 排序 List> lst = new List>(errorDic); lst.Sort(delegate(KeyValuePairs1, KeyValuePairs2) { return s2.Value.CompareTo(s1.Value); }); foreach (KeyValuePairerrorPair in lst) { SaveAsClips(assetPath, errorPair.Value, errorPair.Key, gameObj, exportPath); } float minError = Mathf.Infinity; foreach (KeyValuePairpair in errorDic) { minError = Mathf.Min(minError, pair.Value); } errorDic.Clear(); // 設置回原來的 ImportSettingsHelper.SetImportSettingsCompressionError(assetPath, minError); } else { SaveAsClips(assetPath, 0, string.Empty, gameObj, exportPath); } } else { SaveAsClips(assetPath, 0, string.Empty, gameObj, exportPath); } // 導出prefab string prefabPath = exportPath.Replace(Application.dataPath, "Assets") + obj.name + ".prefab"; //PrefabUtility.CreatePrefab(prefabPath, gameObj); GameObject.DestroyImmediate(gameObj); } EditorUtility.UnloadUnusedAssets(); } void SaveAsClips(string assetPath, float errorValue, string clipName, GameObject gameObj, string exportPath) { if (errorValue > 0) { ImportSettingsHelper.SetImportSettingsCompressionError(assetPath, errorValue); } Object[] objs = AssetDatabase.LoadAllAssetsAtPath(assetPath); for (int j = 0; j < objs.Length; ++j) { if ((objs[j].GetType()) == typeof(AnimationClip)) { if (string.IsNullOrEmpty(clipName) || objs[j].name == clipName) { //UnityEngine.Debug.Log(objs[j].name); AnimationState state = gameObj.GetComponent()[objs[j].name]; if (state == null) continue; // 生成新的AnimationClip AnimationClip newClip = new AnimationClip(); newClip.frameRate = 25; newClip.name = objs[j].name; // 復制數(shù)據(jù) // 方法1:該方法僅設置有效數(shù)據(jù)因块,編輯器相關數(shù)據(jù)不會設置到導出資源中 EditorUtility.CopySerialized(objs[j], newClip); // 方法2:該方法會將編輯器相關數(shù)據(jù)設置到導出資源中 /* EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(objs[j] as AnimationClip); for (int bindIdx = 0; bindIdx < bindings.Length; ++bindIdx) { AnimationCurve curve = AnimationUtility.GetEditorCurve(objs[j] as AnimationClip, bindings[bindIdx]); AnimationUtility.SetEditorCurve(newClip, bindings[bindIdx], curve); } // * */ /* // 方法3:該方法會將編輯器相關數(shù)據(jù)設置到導出資源中 AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(objs[j] as AnimationClip, true); for (int curIdx = 0; curIdx < curveDatas.Length; ++curIdx) { AnimationClipCurveData curve = curveDatas[curIdx]; AnimationUtility.SetEditorCurve(newClip, curve.path, curve.type, curve.propertyName, curve.curve); } * */ // 導出動畫 string animPath = exportPath.Replace(Application.dataPath, "Assets") + objs[j].name + ".anim"; AssetDatabase.CreateAsset(newClip, animPath); string resultPath = animPath.Replace(m_AssetExportPathPrefix, "Resources/Pack/Ani"); resultPath = resultPath.Replace(".anim", ""); AddActionResult(assetPath, resultPath); // 移除動畫 gameObj.GetComponent().RemoveClip(objs[j].name); } } } } public override void OnSelectPath(string path, bool isPath) { if (isPath) { m_AssetList = new List(); path = path.Replace(Application.dataPath, "Assets"); string[] assets = AssetDatabase.FindAssets(m_AssetFilter, new string[] { path }); if (assets != null) { for (int idx = 0; idx < assets.Length; ++idx) { string assetPath = AssetDatabase.GUIDToAssetPath(assets[idx]); FbxInfo fbxInfo = new FbxInfo(); fbxInfo.m_AssetPath = assetPath; fbxInfo.m_AssetName = Path.GetFileName(assetPath); fbxInfo.m_IsExport = true; fbxInfo.m_IsCompress = true; m_AssetList.Add(fbxInfo); } } } else { path = path.Replace(Application.dataPath, "Assets"); path = path.Substring(0, path.LastIndexOf("/")); m_AssetList = new List();
? ? ? ? ? ? ? ? FbxInfo fbxInfo = new FbxInfo();
? ? ? ? ? ? ? ? fbxInfo.m_AssetPath = path;
? ? ? ? ? ? ? ? fbxInfo.m_AssetName = Path.GetFileName(path);
? ? ? ? ? ? ? ? fbxInfo.m_IsExport = true;
? ? ? ? ? ? ? ? fbxInfo.m_IsCompress = true;
? ? ? ? ? ? ? ? m_AssetList.Add(fbxInfo);
? ? ? ? ? ? }
? ? ? ? }
? ? }