UGUI 帧动画插件

18564048_2014061610481056870600


最近在开发一款功夫猫游戏,本来使用Unity Sprite制作,但是发现Sprite对各种分辨率不支持. 看着游戏很简单就使用UGUI制作,在中途发现有很多帧动画播放,使用了Animation调整使用多了的确很不方便.

于是改成脚本来控制Sprite帧动画切换,慢慢开始形成了写一个插件来调整. 写了两个通宵终于搞定了. O(∩_∩)O~

效果图:

image123

代码:

组件类:

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

posted @ 2015-10-22 03:36  盘子脸  阅读(1717)  评论(2编辑  收藏  举报