最近在开发一款功夫猫游戏,本来使用Unity Sprite制作,但是发现Sprite对各种分辨率不支持. 看着游戏很简单就使用UGUI制作,在中途发现有很多帧动画播放,使用了Animation调整使用多了的确很不方便.
于是改成脚本来控制Sprite帧动画切换,慢慢开始形成了写一个插件来调整. 写了两个通宵终于搞定了. O(∩_∩)O~
效果图:
代码:
组件类:
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; using System; /// <summary> /// 帧动画组件 /// </summary> [System.Serializable] public class ImageAnimation : MonoBehaviour { private float animationDeltaTime; public float animationDeltaTimer; public List<AnimationInfoEntity> animationInfo; public int type; public Image visualize; public int index; public string animationTypeList; public string tempAnimationTypeList; public string[] animationTypeProp; public void Awake() { visualize = this.transform.GetComponent<Image>(); } public void Update() { animationDeltaTime += Time.deltaTime; #region List的用法 if (animationInfo != null && animationInfo.Count > 0 && animationDeltaTime > animationInfo[type].deltaTime) { if (animationInfo[type].animationSprite != null && animationInfo[type].animationSprite.Count != 0) { index++; index = index % animationInfo[type].animationSprite.Count; visualize.sprite = animationInfo[type].animationSprite[index]; animationDeltaTime = 0; visualize.SetNativeSize(); } } #endregion } /// <summary> /// 切换动画状态 /// </summary> /// <param name="index">输入动画状态下标值</param> public void ChangeAnimationState(int index) { if (animationTypeProp != null) { if (index < animationTypeProp.Length) { type = index; } } } /// <summary> /// 切换动画状态 /// </summary> /// <param name="animationStateName">输入动画状态的名称</param> public void ChangeAnimationState(string animationStateName) { if (animationTypeProp != null) { for (int i = 0; i < animationTypeProp.Length; i++) { if (animationTypeProp[i].Equals(animationStateName)) { type = i; return; } } } } } [System.Serializable] public class AnimationInfoEntity { /// <summary> /// 动画状态 /// </summary> public int type; /// <summary> /// 播放当前帧需要的时间 /// </summary> public float deltaTime; /// <summary> /// 动画状态所需要的图片集合 /// </summary> public List<Sprite> animationSprite; public AnimationInfoEntity() { } public AnimationInfoEntity(int type, float deltaTime, int spriteNum = 1) { this.type = type; this.deltaTime = deltaTime; animationSprite = new List<Sprite>(); } }
编辑器类:
using UnityEngine; using System.Collections; using UnityEditor; using System.Collections.Generic; using System; using System.Reflection; using System.Reflection.Emit; [CustomEditor(typeof(ImageAnimation))] public class AnimationEditor : Editor { public void OnEnable() { ImageAnimation model = target as ImageAnimation; if (model.tempAnimationTypeList == null) { model.tempAnimationTypeList = string.Empty; } if (model.animationInfo == null) { model.animationInfo = new List<AnimationInfoEntity>(); } } public override void OnInspectorGUI() { ImageAnimation model = target as ImageAnimation; if (!string.IsNullOrEmpty(model.animationTypeList)) { model.animationTypeProp = model.animationTypeList.Split (';'); } #region 动画分割 GUILayout.BeginHorizontal(); GUILayout.Label("所有图片每帧时间: ", new GUILayoutOption[] { GUILayout.Width(120) }); model.animationDeltaTimer = EditorGUILayout.FloatField(model.animationDeltaTimer); if (GUILayout.Button("统一时间")) { for (int j = 0; j < model.animationInfo.Count; j++) { model.animationInfo[j].deltaTime = model.animationDeltaTimer; } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal (); GUILayout.Label("动画类型分隔符: ",new GUILayoutOption[]{ GUILayout.Width(120)}); model.tempAnimationTypeList = GUILayout.TextField(model.tempAnimationTypeList, 50); if (GUILayout.Button ("重新定义动画类型")) { model.animationInfo = new List<AnimationInfoEntity>(); model.animationTypeList = model.tempAnimationTypeList; model.animationTypeProp = model.animationTypeList.Split (';'); //初始化动画类型集合 for (int j = 0; j < model.animationTypeProp.Length; j++) { model.animationInfo.Add(new AnimationInfoEntity(j, model.animationDeltaTimer)); } } GUILayout.EndHorizontal (); #endregion #region 绘制各个动画属性 if (model.animationTypeProp != null && !string.IsNullOrEmpty(model.animationTypeProp[0])) { for (int i = 0; i < model.animationTypeProp.Length; i++) { //draw animation typea GUILayout.BeginHorizontal(); GUILayout.Label("动画类型: ", new GUILayoutOption[] { GUILayout.Width(60) }); int index = EditorGUILayout.Popup(i, model.animationTypeProp, new GUILayoutOption[] { GUILayout.Width(150) }); if (GUILayout.Button("+")) { model.animationInfo[i].animationSprite.Add(new Sprite()); } if (GUILayout.Button("-")) { if (model.animationInfo[i].animationSprite.Count > 0) { model.animationInfo[i].animationSprite.RemoveAt(model.animationInfo[i].animationSprite.Count - 1); } } GUILayout.EndHorizontal(); //draw image list GUILayout.BeginVertical(); if (model.animationInfo != null && model.animationInfo.Count > 0) { for (int k = 0; k < model.animationInfo[i].animationSprite.Count; k++) { GUILayout.BeginHorizontal(); GUILayout.Label("动画帧数: ", new GUILayoutOption[] { GUILayout.Width(60) }); EditorGUILayout.FloatField(model.animationInfo[i].deltaTime, new GUILayoutOption[] { GUILayout.Width(60) }); model.animationInfo[i].animationSprite[k] = EditorGUILayout.ObjectField("增加一个贴图", model.animationInfo[i].animationSprite[k], typeof(Sprite)) as Sprite; GUILayout.EndHorizontal(); } } GUILayout.EndVertical(); } } #endregion serializedObject.ApplyModifiedProperties(); DrawAnimationButton(); } /// <summary> /// 绘制动画切换按钮,方便用户切换动画,查看动画是否正确 /// </summary> private void DrawAnimationButton() { ImageAnimation model = target as ImageAnimation; if (model.animationTypeProp != null) { GUILayout.BeginHorizontal(); GUILayout.Label("切换动画状态: ",GUILayout.Width(80)); for (int i = 0; i < model.animationTypeProp.Length; i++) { if (GUILayout.Button(model.animationTypeProp[i],GUILayout.Width(50))) { model.ChangeAnimationState(i); } } GUILayout.EndHorizontal(); } } }
下载地址: http://yunpan.cn/cFRfdgXhK6ff2 访问密码 3aed