using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEditor; using System.IO; namespace BFEditor.Resource { public static class FrameAnimationTools { const float FRAME_TIME = 0.1f; // 每帧间隔 struct CheckResult { public bool legal; public GameObject gameObject; public Image image; public string spritePath; public string animationPath; public string controllerPath; } public static void CreateFrameAnimation(bool parentAni = false) { var result = CheckLegal(parentAni); if (!result.legal) { return; } if (!File.Exists(result.animationPath)) { var bindingPath = parentAni ? result.gameObject.name : ""; CreateAnimation(result.spritePath, result.animationPath, bindingPath); } else { var bindingPath = parentAni ? result.gameObject.name : ""; ModifyAnimaiton(result.spritePath, result.animationPath, bindingPath); } if (!File.Exists(result.controllerPath)) { var gameObject = parentAni ? result.gameObject.transform.parent.gameObject : result.gameObject; CreateController(gameObject, result.animationPath, result.controllerPath); } else { Debug.Log(result.controllerPath + "已经存在"); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } static CheckResult CheckLegal(bool parentAni = false) { var result = new CheckResult(); var obj = (GameObject)Selection.activeObject; result.gameObject = obj; if (ReferenceEquals(obj, null)) { EditorUtility.DisplayDialog("提示", "当前没有选中的gameObject", "ok"); result.legal = false; return result; } if (parentAni) { var parent = obj.transform.parent; if (parent == null) { EditorUtility.DisplayDialog("提示", "当前没有选中的gameObject没有父物体", "ok"); result.legal = false; return result; } } var image = obj.GetComponent(); result.image = image; if (ReferenceEquals(image, null)) { EditorUtility.DisplayDialog("提示", "当前选中的gameObject没有image组件", "ok"); result.legal = false; return result; } var sprite = image.sprite; if (ReferenceEquals(sprite, null)) { EditorUtility.DisplayDialog("提示", "image.sprite为空", "ok"); result.legal = false; return result; } var path = AssetDatabase.GetAssetPath(sprite).Replace("\\", "/"); result.spritePath = path; if (string.IsNullOrEmpty(path)) { EditorUtility.DisplayDialog("提示", "找不到sprite路径", "ok"); result.legal = false; return result; } var textureImproter = (TextureImporter)AssetImporter.GetAtPath(path); if (textureImproter.spriteImportMode != SpriteImportMode.Multiple) { EditorUtility.DisplayDialog("提示", "spriteImportMode设置不正确", "ok"); result.legal = false; return result; } result.animationPath = path.Replace("png", "anim"); result.controllerPath = path.Replace("png", "controller"); if (File.Exists(result.animationPath)) { var tips = string.Format("已经存在{0}\n确定重置序列帧曲线吗?", result.animationPath); if (!EditorUtility.DisplayDialog("提示", tips, "确定", "取消")) { result.legal = false; return result; } } result.legal = true; return result; } /// /// 创建animation /// static void CreateAnimation(string spritePath, string animationPath, string bindingPath = "") { var clip = new AnimationClip(); clip.frameRate = 60; var clipSettingss = AnimationUtility.GetAnimationClipSettings(clip); clipSettingss.loopTime = true; AnimationUtility.SetAnimationClipSettings(clip, clipSettingss); var curveBuilding = GetCurveBinding(bindingPath); var keyFrames = GetKeyFrames(spritePath); AnimationUtility.SetObjectReferenceCurve(clip, curveBuilding, keyFrames); AssetDatabase.CreateAsset(clip, animationPath); } /// /// 修改animation /// static void ModifyAnimaiton(string spritePath, string animationPath, string bindingPath = "") { var keyFrames = GetKeyFrames(spritePath); var clip = AssetDatabase.LoadAssetAtPath(animationPath); foreach (var binding in AnimationUtility.GetObjectReferenceCurveBindings(clip)) { if (binding.path == bindingPath && binding.propertyName == "m_Sprite") { AnimationUtility.SetObjectReferenceCurve(clip, binding, keyFrames); Debug.Log("重置序列帧曲线"); return; } } var curveBuilding = GetCurveBinding(bindingPath); AnimationUtility.SetObjectReferenceCurve(clip, curveBuilding, keyFrames); } static ObjectReferenceKeyframe[] GetKeyFrames(string spritePath) { // 获取切割出来的sprite var spriteList = new List(); var objs = AssetDatabase.LoadAllAssetsAtPath(spritePath); foreach (var obj in objs) { if (obj is Sprite) { spriteList.Add(obj as Sprite); } } // 创建序列帧曲线 var keyFrames = new ObjectReferenceKeyframe[spriteList.Count]; for (int i = 0; i < spriteList.Count; i++) { var keyFrame = new ObjectReferenceKeyframe(); keyFrame.time = FRAME_TIME * i; keyFrame.value = spriteList[i]; keyFrames[i] = keyFrame; } return keyFrames; } static EditorCurveBinding GetCurveBinding(string bindingPath = "") { var curveBuilding = new EditorCurveBinding(); curveBuilding.path = bindingPath; curveBuilding.propertyName = "m_Sprite"; curveBuilding.type = typeof(Image); return curveBuilding; } /// /// 创建controller /// static void CreateController(GameObject gameObject, string animationPath, string controllerPath) { var animator = gameObject.GetComponent(); if (animator == null) { animator = gameObject.AddComponent(); } var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); var layer = controller.layers[0]; var machine = layer.stateMachine; var stateName = Path.GetFileNameWithoutExtension(animationPath); var animState = machine.AddState(stateName); var clip = AssetDatabase.LoadAssetAtPath(animationPath); animState.motion = clip; machine.AddAnyStateTransition(animState); machine.defaultState = animState; animator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath(controllerPath); } } }