public static T GetColumnUnsafe <T>(this ConfigLine self, string column) { try { return(self.GetColumn <T>(column)); } catch (Exception e) { } return(default(T)); }
public static void AutoClip2() { /* * 读取excel表,获取动画的信息:名字,起始帧,结束帧 * 再读取fbx的动画信息,对名字相同的进行信息merge * merge:起始帧,结束帧 * 保留:event信息,mask信息,curve信息 * 如果有新加的,那么加入新的信息 * **/ // 匿名函数 System.Func <bool, ConfigLine, SerializedProperty, int> SetPropertyFunction = delegate(bool IsHumanClip, ConfigLine csv_line, SerializedProperty sp) { sp.FindPropertyRelative("firstFrame").floatValue = csv_line.GetColumnUnsafe <float>("firstFrame"); sp.FindPropertyRelative("lastFrame").floatValue = csv_line.GetColumnUnsafe <float>("lastFrame"); // LoopTime, LoopPose sp.FindPropertyRelative("loopTime").boolValue = csv_line.GetColumnUnsafe <int>("loopTime") > 0; sp.FindPropertyRelative("loopBlend").boolValue = csv_line.GetColumnUnsafe <int>("loopBlend") > 0; // Rotation_BakeIntoPose, Rotation_BaseUpon sp.FindPropertyRelative("loopBlendOrientation").boolValue = csv_line.GetColumnUnsafe <int>("loopBlendOrientation") > 0; sp.FindPropertyRelative("keepOriginalOrientation").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalOrientation") == 0; // PositionY_BakeIntoPose, PositionY_BaseUpon sp.FindPropertyRelative("loopBlendPositionY").boolValue = csv_line.GetColumnUnsafe <int>("loopBlendPositionY") > 0; if (IsHumanClip) { // 如果是humanoid类型的动画,那么keepOriginalPositionY的取值为0,1,2三种。 sp.FindPropertyRelative("keepOriginalPositionY").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 0; sp.FindPropertyRelative("heightFromFeet").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 2; } else { sp.FindPropertyRelative("keepOriginalPositionY").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 0; } // PositionXZ_BakeIntoPose, PositionXZ_BaseUpon sp.FindPropertyRelative("loopBlendPositionXZ").boolValue = csv_line.GetColumnUnsafe <int>("loopBlendPositionXZ") > 0; sp.FindPropertyRelative("keepOriginalPositionXZ").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionXZ") == 0; return(0); }; // 读取excel string[] files = Directory.GetFiles(Application.dataPath + "/Art/", "animations*.xls", SearchOption.AllDirectories); foreach (var fileName in files) { DateTime excelTime = File.GetLastWriteTime(fileName); Debug.Log("读取xls文件:" + fileName + ", file-write-time=" + excelTime.ToString()); Dictionary <string, ConfigFile> excels = ReadXML(fileName);// ReadXML(Application.dataPath + "/Art/animations.xls"); foreach (var it in excels) { Debug.Log("处理:" + it.Key); ConfigFile csv = it.Value; string[] assets = AssetDatabase.FindAssets(it.Key, new string[] { "Assets/Art" }); if (assets.Length > 0) { string asset = AssetDatabase.GUIDToAssetPath(assets[0]); // 如果.meta时间和excel时间不一样,说明有变化,否则没变化的就直接跳过 DateTime assetMetaTime = File.GetLastWriteTime(asset + ".meta"); if (DateTime.Equals(assetMetaTime, excelTime)) { // 文件没有变化,不处理 Debug.Log("文件没有变化,不处理啦:" + asset); continue; } File.SetLastWriteTime(asset + ".meta", excelTime); ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(asset); SerializedObject serializedObject = modelImporter == null ? null : new SerializedObject(modelImporter); ModelImporterAnimationType m_AnimationType = (ModelImporterAnimationType)serializedObject.FindProperty("m_AnimationType").intValue; bool IsHumanClip = m_AnimationType == ModelImporterAnimationType.Human; HashSet <string> processed_clip = new HashSet <string>(); if (serializedObject == null) { Debug.Log("无法处理该文件:" + asset); } else { // 压缩方式 serializedObject.FindProperty("m_AnimationCompression").intValue = (int)ModelImporterAnimationCompression.Optimal; // 切割或者merge动画 SerializedProperty m_ClipAnimations = serializedObject.FindProperty("m_ClipAnimations"); for (int i = 0; i < m_ClipAnimations.arraySize; i++) { SerializedProperty sp = m_ClipAnimations.GetArrayElementAtIndex(i); string clip_name = sp.FindPropertyRelative("name").stringValue; if (clip_name.Contains("@")) { clip_name = clip_name.Substring(clip_name.LastIndexOf("@") + 1); } ConfigLine csv_line = csv.FindData(clip_name); if (csv_line != null) { processed_clip.Add(clip_name); // merge基本属性 SetPropertyFunction(IsHumanClip, csv_line, sp); // 其他属性,如event,mask,都不处理,保持原来信息 } } // 把剩下没处理的内容,作为新的动画,分割到fbx中 Dictionary <string, ConfigLine> csv_data = csv.GetLines(); foreach (var kt in csv_data) { if (processed_clip.Contains(kt.Key)) { continue; } processed_clip.Add(kt.Key); ConfigLine csv_line = kt.Value; m_ClipAnimations.InsertArrayElementAtIndex(m_ClipAnimations.arraySize); SerializedProperty sp = m_ClipAnimations.GetArrayElementAtIndex(m_ClipAnimations.arraySize - 1); sp.FindPropertyRelative("name").stringValue = it.Key + "@" + kt.Key; sp.FindPropertyRelative("takeName").stringValue = "Take 001"; // 处理基本属性 SetPropertyFunction(IsHumanClip, csv_line, sp); // 设置mask UnityEditorInternal.AvatarMask mask = new UnityEditorInternal.AvatarMask(); mask.transformCount = modelImporter.transformPaths.Length; for (int i = 0; i < modelImporter.transformPaths.Length; i++) { mask.SetTransformPath(i, modelImporter.transformPaths[i]); mask.SetTransformActive(i, true); } SerializedProperty bodyMask = sp.FindPropertyRelative("bodyMask"); if (bodyMask != null && bodyMask.isArray) { for (int i = 0; i < mask.humanoidBodyPartCount; i++) { if (i >= bodyMask.arraySize) { bodyMask.InsertArrayElementAtIndex(i); } bodyMask.GetArrayElementAtIndex(i).intValue = mask.GetHumanoidBodyPartActive(i) ? 1 : 0; } } SerializedProperty transformMask = sp.FindPropertyRelative("transformMask"); //ModelImporter.UpdateTransformMask(mask, transformMask); Type ty = typeof(ModelImporter); MethodInfo mi = ty.GetMethod("UpdateTransformMask", BindingFlags.Static | BindingFlags.NonPublic); if (mi != null) { mi.Invoke(null, new object[] { mask, transformMask }); } else { Debug.LogError("无法找到此方法!"); } } serializedObject.ApplyModifiedProperties(); AssetDatabase.WriteImportSettingsIfDirty(asset); AssetDatabase.ImportAsset(asset); } } else { Debug.LogError("无法找到这个FBX文件:" + it.Key); } } } }