void _ParseFunction(AnimConfigItem.AnimEvent key, string keyFrame, string funcItem) { key.keyFrame = int.Parse(keyFrame); string funcName = funcItem; string param = ""; int funcIdx = funcItem.IndexOf("("); if (funcIdx != -1) { funcName = funcItem.Substring(0, funcIdx); int iParam = funcItem.IndexOf(")"); if (iParam != -1) { param = funcItem.Substring(funcIdx + 1, funcItem.Length - funcIdx - 2); key.stringParameter = param; key.paramCnt++; } } key.eventFunctionName = funcName; }
public bool ReadConfig(string strConfigPath, out List <AnimConfigItem> configs) { configs = new List <AnimConfigItem>(); try { using (FileStream fs = new FileStream(strConfigPath, FileMode.Open)) { TextReader reader = new StreamReader(fs); while (true) { string strConfigContent = reader.ReadLine(); if (strConfigContent == null) { break; } int comments = strConfigContent.IndexOf("//"); if (comments != -1) { strConfigContent = strConfigContent.Substring(0, comments); } strConfigContent = strConfigContent.Trim(); if (strConfigContent.Length == 0) { continue; } string[] strConfigItems = strConfigContent.Split(','); if (strConfigItems.Length < 4) { Debug.LogError("Invalid animConfig format: " + strConfigContent); break; } foreach (string strConfigItem in strConfigItems) { strConfigItem.Trim(); } AnimConfigItem animConfigItem = new AnimConfigItem(); animConfigItem.name = strConfigItems[0]; animConfigItem.name = animConfigItem.name.Trim(); animConfigItem.startFrame = int.Parse(strConfigItems[1]); animConfigItem.endFrame = int.Parse(strConfigItems[2]); animConfigItem.wrapMode = AnimConfigItem.Parse(strConfigItems[3]); for (int idx = 4; idx < strConfigItems.GetLength(0); idx += 2) { AnimConfigItem.AnimEvent key = new AnimConfigItem.AnimEvent(); _ParseFunction(key, strConfigItems[idx], strConfigItems[idx + 1].Trim()); animConfigItem.animEvents.Add(key); } configs.Add(animConfigItem); } } return(true); } catch (IOException exp) { Debug.LogError("读取动作文件配置失败: " + exp.Message); } return(false); }
static public void SplitAnimation() { if (Selection.activeObject == null) { return; } Debug.Log("当前选择:" + Selection.activeObject); GameObject fbxFile = Selection.activeObject as GameObject; if (fbxFile == null) { return; } string targetAnimPath = AssetDatabase.GetAssetPath(Selection.activeObject); AssetImporter assetImporter = AssetImporter.GetAtPath(targetAnimPath); ModelImporter modelImporter = assetImporter as ModelImporter; if (modelImporter == null) { EditorUtility.DisplayDialog("AnimationEditor", "找不到角色,请先选中角色", "Ok"); return; } if (modelImporter.animationType != ModelImporterAnimationType.Legacy) { if (EditorUtility.DisplayDialog("AnimationEditor", "是否修改为Legacy动画?", "Yes", "No")) { modelImporter.animationType = ModelImporterAnimationType.Legacy; } } string dir = Path.GetDirectoryName(targetAnimPath); string configPath = EditorUtility.OpenFilePanel("动画配置文件", dir, "animConfig"); if (configPath.Length == 0) { return; } List <AnimConfigItem> configs; if (!PlayerActConfig.Instance.ReadConfig(configPath, out configs)) { EditorUtility.DisplayDialog("AnimationEditor", "读取动画配置文件失败", "Ok"); return; } ClipSplitter splitter = new ClipSplitter(); foreach (AnimConfigItem item in configs) { splitter.AddClip(string.Format("{0}", item.name), item.startFrame, item.endFrame, item.wrapMode); } //append /* * List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(); * foreach( ModelImporterClipAnimation destClip in modelImporter.clipAnimations ) * clips.Add( destClip ); * ModelImporterClipAnimation[] srcClips = splitter.getArray(); * foreach( ModelImporterClipAnimation clip in srcClips ) * { * int idx = clips.FindIndex( delegate(ModelImporterClipAnimation inClip) { return inClip.name == clip.name; } ); * if( idx != -1 ) * clips[idx] = clip; * else * clips.Add( clip ); * } */ /* * AnimationClip[] clipsInFbx = AnimationUtility.GetAnimationClips(fbxFile.animation); * if( clipsInFbx.Length == 0 ) * { * EditorUtility.DisplayDialog ("AnimationEditor", "FBX文件没有动画导入,请检查fbx Animations是否已勾选import animation", "Ok"); * return; * } */ modelImporter.importAnimation = true; //remove modelImporter.clipAnimations = splitter.getArray(); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(targetAnimPath); string animPackPath = Path.Combine(Path.GetDirectoryName(targetAnimPath), "animation"); if (Directory.Exists(animPackPath)) { if (EditorUtility.DisplayDialog("AnimationEditor", "是否清空已有动画?", "Yes", "No")) { string[] files = Directory.GetFiles(animPackPath); foreach (string file in files) { AssetDatabase.DeleteAsset(file); } } } else { AssetDatabase.CreateFolder(Path.GetDirectoryName(targetAnimPath), "animation"); } //depulicated animation AnimationClip[] clipsInFbx = AnimationUtility.GetAnimationClips(fbxFile.GetComponent <Animation>()); foreach (AnimationClip sourceClip in clipsInFbx) { string path = Path.Combine(animPackPath, sourceClip.name) + ".anim"; string newPath = AssetDatabase.GenerateUniqueAssetPath(path); AnimationClip newClip = new AnimationClip(); EditorUtility.CopySerialized(sourceClip, newClip); AnimConfigItem item = configs.Find(delegate(AnimConfigItem inClip) { return(inClip.name == newClip.name); }); if (item != null && item.animEvents.Count != 0) { AnimationEvent[] animEvent = new AnimationEvent[item.animEvents.Count]; for (int idx = 0; idx != item.animEvents.Count; idx++) { AnimConfigItem.AnimEvent eventItem = item.animEvents[idx]; animEvent[idx] = new AnimationEvent(); animEvent[idx].time = Mathf.Approximately((float)(item.endFrame - item.startFrame), 0.0f)? 0.0f : (float)(eventItem.keyFrame - item.startFrame) / (float)(item.endFrame - item.startFrame) * newClip.length; animEvent[idx].functionName = eventItem.eventFunctionName; animEvent[idx].stringParameter = eventItem.stringParameter; //Dictionary<string, string> param = AnimConfigItem.ParseParam(animEvent[idx].stringParameter); //foreach( KeyValuePair<string, string> keyValue in param ) // Debug.Log( keyValue.Key + " " + keyValue.Value ); } AnimationUtility.SetAnimationEvents(newClip, animEvent); } AssetDatabase.CreateAsset(newClip, newPath); } }