Unity2D-------在不使用SpriteRenderer情況下,根據圖片自動生成動畫
阿新 • • 發佈:2019-01-25
仿照 雨鬆MOMO 寫了一個自動生成動畫的指令碼 原地址 http://www.xuanyusong.com/archives/3243
新增選單Tools/CreateAnimation,彈出視窗
你需要設定動畫名、是否迴圈及動畫播放幀率,拖入一張待生成動畫的圖片。
using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEngine.UI; using System.IO; using UnityEditor.Animations; public class CreateAnimation : EditorWindow { string AnimationName = ""; Texture2D ImageName; //圖片所在資料夾位置 string ImagePath = ""; //動畫存放位置 string AnimationPath = ""; //預製體存放位置 string PrefabPath = ""; //動畫是否迴圈 bool showBtn = true; //動畫幀率 string frameRate = ""; //定義彈出當前視窗的選單位置 [MenuItem("Tools/CreateAnimation")] static void Init() { //彈出視窗 EditorWindow.GetWindow(typeof(CreateAnimation)); } void OnGUI() { AnimationName = EditorGUILayout.TextField("待生成的動畫名:", AnimationName); EditorGUILayout.BeginHorizontal(); ImageName = (Texture2D)EditorGUILayout.ObjectField("待用第一張圖片:", ImageName, typeof(Texture2D)); EditorGUILayout.EndHorizontal(); showBtn = EditorGUILayout.Toggle("是否迴圈", showBtn); frameRate = EditorGUILayout.TextField("動畫幀率(預設30):", frameRate); ImagePath = EditorGUILayout.TextField("圖片獲取路徑:", ImagePath); AnimationPath = EditorGUILayout.TextField("動畫生成位置:", AnimationPath); PrefabPath = EditorGUILayout.TextField("預製體生成位置:", PrefabPath); if (GUI.Button(new Rect(Screen.width / 4, 200, Screen.width / 2, 30), "生成動畫")) { BuildAnimation(); } } void BuildAnimation() { if (AnimationName == "" || ImageName == null) { Debug.LogError("沒有給動畫命名或沒有選入圖片"); return; } if (ImagePath != null) { ImagePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(ImageName)); string[] _tempPath = Path.GetDirectoryName(ImagePath).Split('/'); string ss = ""; AnimationPath = _tempPath[0] + "/Animation"; PrefabPath = _tempPath[0] + "/Resources/Prefabs"; for (int i = 2; i < _tempPath.Length; i++) { ss += ("/" + _tempPath[i]); } AnimationPath += (ss + "/" + _tempPath[_tempPath.Length - 1] + "_anim"); PrefabPath += (ss + "/" + _tempPath[_tempPath.Length - 1] + "_Prefab"); //建立資料夾 Directory.CreateDirectory(AnimationPath); Directory.CreateDirectory(PrefabPath); } DirectoryInfo info = new DirectoryInfo(Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/")) + "/" + ImagePath); //Debug.Log(info); List<AnimationClip> clips = new List<AnimationClip>(); clips.Add(BuildAnimationClip(info)); AnimatorController controller = BuildAnimationController(clips); BuildPrefab(info, controller); } AnimationClip BuildAnimationClip(DirectoryInfo dictorys) { string animationName = dictorys.Name; List<FileInfo> images = new List<FileInfo>(); foreach (FileInfo fi in dictorys.GetFiles()) { if (fi.Extension.Equals(".png") && !fi.Extension.Equals(".meta")) { images.Add(fi); } } AnimationClip clip = new AnimationClip(); EditorCurveBinding curveBinding = new EditorCurveBinding(); curveBinding.type = typeof(Image); curveBinding.path = ""; curveBinding.propertyName = "m_Sprite"; ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Count]; float frameTime = 1 / 10f; for (int i = 0; i < images.Count; i++) { Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName)); keyFrames[i] = new ObjectReferenceKeyframe(); keyFrames[i].time = frameTime * i; keyFrames[i].value = sprite; } if (frameRate == "") { clip.frameRate = 30; frameRate = "30"; } else { clip.frameRate = int.Parse(frameRate); } if (showBtn) { SerializedObject serializedClip = new SerializedObject(clip); AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings")); clipSettings.loopTime = true; serializedClip.ApplyModifiedProperties(); } AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames); AssetDatabase.CreateAsset(clip, AnimationPath + "/" + AnimationName + ".anim"); AssetDatabase.SaveAssets(); return clip; } AnimatorController BuildAnimationController(List<AnimationClip> clips) { AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationPath + "/" + AnimationName + ".controller"); AnimatorControllerLayer layer = animatorController.layers[0]; AnimatorStateMachine sm = layer.stateMachine; foreach (AnimationClip newClip in clips) { AnimatorState state = sm.AddState(newClip.name); state.motion = newClip; } AssetDatabase.SaveAssets(); return animatorController; } void BuildPrefab(DirectoryInfo dictorys, AnimatorController animatorCountorller) { FileInfo images = dictorys.GetFiles("*.png")[0]; GameObject go = new GameObject(); go.name = AnimationName; Image img = go.AddComponent<Image>(); go.GetComponent<RectTransform>().sizeDelta = new Vector2(ImageName.width, ImageName.height); img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images.FullName)); Animator animator = go.AddComponent<Animator>(); animator.runtimeAnimatorController = animatorCountorller; PrefabUtility.CreatePrefab(PrefabPath +"/" + AnimationName + ".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/")); } }
using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class AnimationClipSettings : Editor { 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; } } }