diff --git a/Packages/com.nekometer.esnya.esnya-unity-tools/Editor/AnimationTool.cs b/Packages/com.nekometer.esnya.esnya-unity-tools/Editor/AnimationTool.cs index 60316c6..c7d7ac9 100644 --- a/Packages/com.nekometer.esnya.esnya-unity-tools/Editor/AnimationTool.cs +++ b/Packages/com.nekometer.esnya.esnya-unity-tools/Editor/AnimationTool.cs @@ -34,8 +34,8 @@ private void OnGUI() serializedObject.Update(); var property = serializedObject.GetIterator(); property.NextVisible(true); - while (property.NextVisible(false)) - { + while (property.NextVisible(false)) + { if (property.name == nameof(parameterName)) { if (animatorController) @@ -53,7 +53,8 @@ private void OnGUI() layerIndex = EditorGUILayout.Popup("Layer", layerIndex, animatorController.layers.Select(l => l.name).ToArray()); } } - else { + else + { EditorGUILayout.PropertyField(property, true); } } @@ -148,15 +149,26 @@ private static AnimatorControllerLayer AddLayerWithWeiht(AnimatorController anim [MenuItem("Assets/EsnyaTools/Auto Mask")] private static void AutoMaskMenu() { + var tasks = Selection.objects + .Where(o => o is AnimationClip) + .Select(o => o as AnimationClip) + .Select((clip) => (modelImporter: AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(clip)) as ModelImporter, clip)) + .ToArray(); + AssetDatabase.StartAssetEditing(); try { - foreach (var clip in Selection.objects.Where(o => o is AnimationClip).Select(o => o as AnimationClip)) - { - var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(clip)) as ModelImporter; - AutoMask(importer, clip); - importer.SaveAndReimport(); - } + foreach (var (modelImporter, clip) in tasks) AutoMaskPass1(modelImporter, clip); + } + finally + { + AssetDatabase.StopAssetEditing(); + } + + AssetDatabase.StartAssetEditing(); + try + { + foreach (var (modelImporter, clip) in tasks) AutoMaskPass2(modelImporter, clip); } finally { @@ -199,14 +211,27 @@ private static bool IsChildOfModel(AnimationClip clip) return AssetImporter.GetAtPath(path) is ModelImporter; } - public static void AutoMask(ModelImporter modelImporter, AnimationClip clip, bool unmask = false) + private static void AutoMaskPass1(ModelImporter modelImporter, AnimationClip clip, bool unmask = false) { var serializedImporter = new SerializedObject(modelImporter); - var clipAnimationIndex = modelImporter.clipAnimations.Select(a => a.name).TakeWhile(a => a != clip.name).Count(); var clipAnimationProperty = serializedImporter.FindProperty("m_ClipAnimations").GetArrayElementAtIndex(clipAnimationIndex); clipAnimationProperty.FindPropertyRelative(nameof(ModelImporterClipAnimation.maskType)).intValue = (int)(unmask ? ClipAnimationMaskType.None : ClipAnimationMaskType.CreateFromThisModel); + serializedImporter.ApplyModifiedProperties(); + + if (!unmask) + { + modelImporter.CreateDefaultMaskForClip(modelImporter.clipAnimations[clipAnimationIndex]); + modelImporter.SaveAndReimport(); + } + } + public static void AutoMaskPass2(ModelImporter modelImporter, AnimationClip clip, bool unmask = false) + { + var serializedImporter = new SerializedObject(modelImporter); + + var clipAnimationIndex = modelImporter.clipAnimations.Select(a => a.name).TakeWhile(a => a != clip.name).Count(); + var clipAnimationProperty = serializedImporter.FindProperty("m_ClipAnimations").GetArrayElementAtIndex(clipAnimationIndex); var maskProperty = clipAnimationProperty.FindPropertyRelative("transformMask"); if (unmask) @@ -235,7 +260,38 @@ public static void AutoMask(ModelImporter modelImporter, AnimationClip clip, boo elementProperty.FindPropertyRelative("m_Weight").floatValue = (value || unmask) ? 1.0f : 0.0f; } } + serializedImporter.ApplyModifiedProperties(); } + + public static void AutoMask(ModelImporter modelImporter, AnimationClip clip, bool unmask = false) + { + AutoMaskPass1(modelImporter, clip, unmask); + AutoMaskPass2(modelImporter, clip, unmask); + } + + [MenuItem("CONTEXT/ModelImporter/Add Default Clip Animations")] + private static void AddDefaultClipAnimations(MenuCommand menuCommand) + { + var modelImporter = menuCommand.context as ModelImporter; + + var serializedModelImporter = new SerializedObject(modelImporter); + + var clipAnimationsProperty = serializedModelImporter.FindProperty("m_ClipAnimations"); + var internalIds = Enumerable.Range(0, clipAnimationsProperty.arraySize).Select(i => clipAnimationsProperty.GetArrayElementAtIndex(i).FindPropertyRelative("internalID").intValue).ToArray(); + + var existingTakeNames = modelImporter.clipAnimations.ToDictionary(a => a.takeName, a => a); + var existingNames = modelImporter.clipAnimations.ToDictionary(a => a.name, a => a); + modelImporter.clipAnimations = modelImporter.clipAnimations.Concat(modelImporter.defaultClipAnimations.Where(a => !existingNames.ContainsKey(a.takeName) && !existingNames.ContainsKey(a.takeName))).ToArray(); + + serializedModelImporter.Update(); + foreach (var i in Enumerable.Range(0, internalIds.Length)) + { + clipAnimationsProperty.GetArrayElementAtIndex(i).FindPropertyRelative("internalID").intValue = internalIds[i]; + } + serializedModelImporter.ApplyModifiedProperties(); + + modelImporter.SaveAndReimport(); + } } } diff --git a/package.json b/package.json index ac34652..25192b8 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "Packages/*" ], "scripts": { - "version": "npm version -ws ${npm_package_version} && npx -ws sort-package-json", - "publish": "npm publish -ws" + "publish": "npm publish -ws", + "version": "npm version -ws ${npm_package_version} && npx -ws sort-package-json" }, "devDependencies": { "@iam1337/create-unitypackage": "^1.0.4",