Unity製做2D產品的時候,咱們在製做動畫的時候,要不斷的生成Animation,Animator等等資源,若是動畫一多的話,就變得麻煩。因爲Unity是支持插件開發的,咱們能夠添加一個Editor,而後把美術的動畫圖片放在指定的位置。oop
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEditor.Animations; public class BuildAnimation : Editor { //生成出的Prefab的路徑 private static string PrefabPath = "Assets/Resources/Prefabs"; //生成出的AnimationController的路徑 private static string AnimationControllerPath = "Assets/AnimationController"; //生成出的Animation的路徑 private static string AnimationPath = "Assets/Animation"; //美術給的原始圖片路徑 private static string ImagePath = Application.dataPath +"/Raw"; [MenuItem("Build/BuildAnimaiton")] static void BuildAniamtion() { DirectoryInfo raw = new DirectoryInfo (ImagePath); foreach (DirectoryInfo dictorys in raw.GetDirectories()) { List<AnimationClip> clips = new List<AnimationClip>(); foreach (DirectoryInfo dictoryAnimations in dictorys.GetDirectories()) { //每一個文件夾就是一組幀動畫,這裏把每一個文件夾下的全部圖片生成出一個動畫文件 clips.Add(BuildAnimationClip(dictoryAnimations)); } //把全部的動畫文件生成在一個AnimationController裏 AnimatorController controller = BuildAnimationController(clips,dictorys.Name); //最後生成程序用的Prefab文件 BuildPrefab(dictorys,controller); } } static AnimationClip BuildAnimationClip(DirectoryInfo dictorys) { string animationName = dictorys.Name; //查找全部圖片,由於我找的測試動畫是.jpg FileInfo []images = dictorys.GetFiles("*.png"); AnimationClip clip = new AnimationClip(); //AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic); EditorCurveBinding curveBinding = new EditorCurveBinding(); curveBinding.type = typeof(SpriteRenderer); curveBinding.path=""; curveBinding.propertyName = "m_Sprite"; ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length]; //動畫長度是按秒爲單位,1/10就表示1秒切10張圖片,根據項目的狀況能夠本身調節 float frameTime = 1/10f; for(int i =0; i< images.Length; i++){ Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName)); keyFrames[i] = new ObjectReferenceKeyframe (); keyFrames[i].time = frameTime *i; keyFrames[i].value = sprite; } //動畫幀率,30比較合適 clip.frameRate = 30; //有些動畫我但願天生它就動畫循環 if(animationName.IndexOf("idle") >=0 ) { //設置idle文件爲循環動畫 SerializedObject serializedClip = new SerializedObject(clip); AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings")); clipSettings.loopTime = true; serializedClip.ApplyModifiedProperties(); } string parentName = System.IO.Directory.GetParent(dictorys.FullName).Name; System.IO.Directory.CreateDirectory(AnimationPath +"/"+parentName); AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames); AssetDatabase.CreateAsset(clip,AnimationPath +"/"+parentName +"/" +animationName+".anim"); AssetDatabase.SaveAssets(); return clip; } static AnimatorController BuildAnimationController(List<AnimationClip> clips ,string name) { AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationControllerPath +"/"+name+".controller"); AnimatorControllerLayer layer = animatorController.layers[0]; AnimatorStateMachine sm = layer.stateMachine; foreach(AnimationClip newClip in clips) { //AnimatorStateMachine machine = sm.AddStateMachine(newClip.name); AnimatorState state = sm.AddState(newClip.name); state.motion = newClip; //AnimatorStateTransition trans = sm.AddAnyStateTransition(state); if(newClip.name == "idle"){ sm.defaultState = state; } //sm.AddEntryTransition(machine); //sm.AddStateMachineExitTransition(machine); //trans.RemoveCondition(0); } AssetDatabase.SaveAssets(); return animatorController; } static void BuildPrefab(DirectoryInfo dictorys,AnimatorController animatorCountorller) { //生成Prefab 添加一張預覽用的Sprite FileInfo images = dictorys.GetDirectories()[0].GetFiles("*.png")[0]; GameObject go = new GameObject(); go.name = dictorys.Name; SpriteRenderer spriteRender =go.AddComponent<SpriteRenderer>(); spriteRender.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images.FullName)); Animator animator = go.AddComponent<Animator>(); animator.runtimeAnimatorController = animatorCountorller; PrefabUtility.CreatePrefab(PrefabPath+"/"+go.name+".prefab",go); DestroyImmediate(go); } public static string DataPathToAssetPath(string path) { if (Application.platform == RuntimePlatform.WindowsEditor) return path.Substring(path.IndexOf("Assets\\")); else return path.Substring(path.IndexOf("Assets/")); } class AnimationClipSettings { SerializedProperty m_Property; private SerializedProperty Get (string property) { return m_Property.FindPropertyRelative(property); } public AnimationClipSettings(SerializedProperty prop) { m_Property = prop; } public float startTime { get { return Get("m_StartTime").floatValue; } set { Get("m_StartTime").floatValue = value; } } public float stopTime { get { return Get("m_StopTime").floatValue; } set { Get("m_StopTime").floatValue = value; } } public float orientationOffsetY { get { return Get("m_OrientationOffsetY").floatValue; } set { Get("m_OrientationOffsetY").floatValue = value; } } public float level { get { return Get("m_Level").floatValue; } set { Get("m_Level").floatValue = value; } } public float cycleOffset { get { return Get("m_CycleOffset").floatValue; } set { Get("m_CycleOffset").floatValue = value; } } public bool loopTime { get { return Get("m_LoopTime").boolValue; } set { Get("m_LoopTime").boolValue = value; } } public bool loopBlend { get { return Get("m_LoopBlend").boolValue; } set { Get("m_LoopBlend").boolValue = value; } } public bool loopBlendOrientation { get { return Get("m_LoopBlendOrientation").boolValue; } set { Get("m_LoopBlendOrientation").boolValue = value; } } public bool loopBlendPositionY { get { return Get("m_LoopBlendPositionY").boolValue; } set { Get("m_LoopBlendPositionY").boolValue = value; } } public bool loopBlendPositionXZ { get { return Get("m_LoopBlendPositionXZ").boolValue; } set { Get("m_LoopBlendPositionXZ").boolValue = value; } } public bool keepOriginalOrientation { get { return Get("m_KeepOriginalOrientation").boolValue; } set { Get("m_KeepOriginalOrientation").boolValue = value; } } public bool keepOriginalPositionY { get { return Get("m_KeepOriginalPositionY").boolValue; } set { Get("m_KeepOriginalPositionY").boolValue = value; } } public bool keepOriginalPositionXZ { get { return Get("m_KeepOriginalPositionXZ").boolValue; } set { Get("m_KeepOriginalPositionXZ").boolValue = value; } } public bool heightFromFeet { get { return Get("m_HeightFromFeet").boolValue; } set { Get("m_HeightFromFeet").boolValue = value; } } public bool mirror { get { return Get("m_Mirror").boolValue; } set { Get("m_Mirror").boolValue = value; } } } }
以上代碼支持Unity5.0以上。測試
代碼拷貝進去本身試試就知道了,很是方便動畫