using UnityEditor; using UnityEngine; using System.Collections.Generic; using System.Reflection; public class CreateAnimationClip : AssetPostprocessor { void OnPreprocessAnimation() { var modelImporter = assetImporter as ModelImporter; if(modelImporter.clipAnimations.Length == 0) { modelImporter.clipAnimations = modelImporter.defaultClipAnimations; } } } public class AnimationEventCopier : EditorWindow { static private AnimationClip sourceObject; static private AnimationClip targetObject; [MenuItem("Window/Animation Event Copier")] static void Init() { GetWindow(typeof(AnimationEventCopier)); } void OnGUI() { GUIStyle warning = new GUIStyle(GUI.skin.label); warning.normal.textColor = Color.yellow; EditorGUILayout.BeginHorizontal(); sourceObject = EditorGUILayout.ObjectField("Source", sourceObject, typeof(AnimationClip), true) as AnimationClip; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); targetObject = EditorGUILayout.ObjectField("Target", targetObject, typeof(AnimationClip), true) as AnimationClip; EditorGUILayout.EndHorizontal(); if (sourceObject != null) { if ((sourceObject as AnimationClip).events.Length > 0) { GUILayout.Space(10); GUILayout.Label("Events To Be Copied", EditorStyles.boldLabel); GUIStyle rightAligned = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.UpperRight }; foreach (AnimationEvent animationEvent in (sourceObject as AnimationClip).events) { EditorGUILayout.BeginHorizontal(); GUILayout.Label(animationEvent.functionName, EditorStyles.label); GUILayout.Label($"@{animationEvent.time} s", rightAligned); EditorGUILayout.EndHorizontal(); } } else { GUILayout.Space(10); GUILayout.Label("Warning : Source Clip has No Event", warning); } } if (targetObject != null && (targetObject as AnimationClip).events.Length > 0) { GUILayout.Space(10); warning.normal.textColor = Color.red; GUILayout.Label("Warning : Target Clip already has events and will be overwritten", warning); } if (sourceObject != null && targetObject != null) { GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy")) DoAddEvent(); EditorGUILayout.EndHorizontal(); } } static void DoAddEvent() { AnimationClip sourceAnimClip = sourceObject as AnimationClip; AnimationClip targetAnimClip = targetObject as AnimationClip; if ((targetAnimClip.hideFlags & HideFlags.NotEditable) != 0) DoAddEventImportedClip(sourceAnimClip, targetAnimClip); else DoAddEventClip(sourceAnimClip, targetAnimClip); } static void DoAddEventClip(AnimationClip sourceAnimClip, AnimationClip targetAnimClip) { if (sourceAnimClip != targetAnimClip) { AnimationEvent[] sourceAnimEvents = AnimationUtility.GetAnimationEvents(sourceAnimClip); AnimationUtility.SetAnimationEvents(targetAnimClip, sourceAnimEvents); } } static void DoAddEventImportedClip(AnimationClip sourceAnimClip, AnimationClip targetAnimClip) { ModelImporter modelImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(targetAnimClip)) as ModelImporter; if (modelImporter == null) return; SerializedObject serializedObject = new SerializedObject(modelImporter); SerializedProperty clipAnimations = serializedObject.FindProperty("m_ClipAnimations"); if (!clipAnimations.isArray) return; for (int i = 0; i < clipAnimations.arraySize; i++) { AnimationClipInfoProperties clipInfoProperties = new AnimationClipInfoProperties(clipAnimations.GetArrayElementAtIndex(i)); if (clipInfoProperties.name == targetAnimClip.name) { AnimationEvent[] sourceAnimEvents = AnimationUtility.GetAnimationEvents(sourceAnimClip); foreach(AnimationEvent animationEvent in sourceAnimEvents) { float lastTime = animationEvent.time; animationEvent.time *= 1f/ sourceAnimClip.length; Debug.Log($"{animationEvent.functionName} changed to {animationEvent.time} from {lastTime}"); } clipInfoProperties.SetEvents(sourceAnimEvents); serializedObject.ApplyModifiedProperties(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(targetAnimClip)); break; } } } }