首页 > 代码库 > Unity NGUI实现序列帧动画播放

Unity NGUI实现序列帧动画播放

  如题,要实现序列帧的播放导入图片的时候需要注意:

  (1)图片的命名要连续,如图:

  

  (2)将这些图片在NGUI中打包成Altas图集的时候图片应该在同一个Altas中;

  

  这里以播放特效为例,满足条件时播放特效,不满足条件时不播放特效。接下来可以创建一个Sprite,然后用代码控制序列帧特效的播放和停止:

播放:

if (something == false){    this._power_effect_sprite.GetComponent<UISprite>().enabled = true;    UISpriteAnimation uiAnim = _power_effect_sprite.AddComponent<UISpriteAnimation>();    // 设置图片的大小是否更改    uiAnim.Snap = false;    uiAnim.framesPerSecond = 10;    this.isPlayAnimation = true;}

停止:

if (this.isPlayAnimation == true){
  Destroy(_power_effect_sprite.GetComponent
<UISpriteAnimation>());  UISprite ui = _power_effect_sprite.GetComponent<UISprite>();  ui.spriteName = ui.atlas.spriteList[0].name;  this._power_effect_sprite.GetComponent<UISprite>().enabled = false;}

  _power_effect_sprite表示创建的sprite,当满足条件时,代码会添加为sprite添加一个UISpriteAnimation.cs脚本来控制图片的按序播放,注意播放代码中的设置图片的大小是否更改的代码:

uiAnim.Snap = false;

  这是按需求更改了NGUI的UISpriteAnimation.cs的脚本代码,为脚本中的mSnap变量添加了设置接口,可以比较原代码和更改后的UISpriteAnimation代码:

原UISpriteAnimation代码:

//----------------------------------------------//            NGUI: Next-Gen UI kit// Copyright © 2011-2014 Tasharen Entertainment//----------------------------------------------using UnityEngine;using System.Collections.Generic;/// <summary>/// Very simple sprite animation. Attach to a sprite and specify a common prefix such as "idle" and it will cycle through them./// </summary>[ExecuteInEditMode][RequireComponent(typeof(UISprite))][AddComponentMenu("NGUI/UI/Sprite Animation")]public class UISpriteAnimation : MonoBehaviour{    [HideInInspector][SerializeField] protected int mFPS = 30;    [HideInInspector][SerializeField] protected string mPrefix = "";    [HideInInspector][SerializeField] protected bool mLoop = true;    [HideInInspector][SerializeField] protected bool mSnap = true;    protected UISprite mSprite;    protected float mDelta = 0f;    protected int mIndex = 0;    protected bool mActive = true;    protected List<string> mSpriteNames = new List<string>();    /// <summary>    /// Number of frames in the animation.    /// </summary>    public int frames { get { return mSpriteNames.Count; } }    /// <summary>    /// Animation framerate.    /// </summary>    public int framesPerSecond { get { return mFPS; } set { mFPS = value; } }    /// <summary>    /// Set the name prefix used to filter sprites from the atlas.    /// </summary>    public string namePrefix { get { return mPrefix; } set { if (mPrefix != value) { mPrefix = value; RebuildSpriteList(); } } }    /// <summary>    /// Set the animation to be looping or not    /// </summary>    public bool loop { get { return mLoop; } set { mLoop = value; } }    /// <summary>    /// Returns is the animation is still playing or not    /// </summary>    public bool isPlaying { get { return mActive; } }    /// <summary>    /// Rebuild the sprite list first thing.    /// </summary>    protected virtual void Start ()     {        RebuildSpriteList(); }    /// <summary>    /// Advance the sprite animation process.    /// </summary>    protected virtual void Update ()    {        if (mActive && mSpriteNames.Count > 1 && Application.isPlaying && mFPS > 0f)        {            mDelta += RealTime.deltaTime;            float rate = 1f / mFPS;            if (rate < mDelta)            {                                mDelta = (rate > 0f) ? mDelta - rate : 0f;                if (++mIndex >= mSpriteNames.Count)                {                    mIndex = 0;                    mActive = loop;                }                if (mActive)                {                    mSprite.spriteName = mSpriteNames[mIndex];                    if (mSnap)                    {                        mSprite.MakePixelPerfect();                    }                }            }        }    }    /// <summary>    /// Rebuild the sprite list after changing the sprite name.    /// </summary>    public void RebuildSpriteList ()    {        if (mSprite == null) mSprite = GetComponent<UISprite>();        mSpriteNames.Clear();        if (mSprite != null && mSprite.atlas != null)        {            List<UISpriteData> sprites = mSprite.atlas.spriteList;            for (int i = 0, imax = sprites.Count; i < imax; ++i)            {                UISpriteData sprite = sprites[i];                if (string.IsNullOrEmpty(mPrefix) || sprite.name.StartsWith(mPrefix))                {                    mSpriteNames.Add(sprite.name);                }            }            mSpriteNames.Sort();        }    }        /// <summary>    /// Reset the animation to frame 0 and activate it.    /// </summary>        public void Reset()    {        mActive = true;        mIndex = 0;        if (mSprite != null && mSpriteNames.Count > 0)        {            mSprite.spriteName = mSpriteNames[mIndex];            if (mSnap) mSprite.MakePixelPerfect();        }    }}
View Code

更改后的UISpriteAnimation代码:

  1 //----------------------------------------------  2 //            NGUI: Next-Gen UI kit  3 // Copyright © 2011-2014 Tasharen Entertainment  4 //----------------------------------------------  5   6 using UnityEngine;  7 using System.Collections.Generic;  8   9 /// <summary> 10 /// Very simple sprite animation. Attach to a sprite and specify a common prefix such as "idle" and it will cycle through them. 11 /// </summary> 12  13 [ExecuteInEditMode] 14 [RequireComponent(typeof(UISprite))] 15 [AddComponentMenu("NGUI/UI/Sprite Animation")] 16 public class UISpriteAnimation : MonoBehaviour 17 { 18     [HideInInspector][SerializeField] protected int mFPS = 30; 19     [HideInInspector][SerializeField] protected string mPrefix = ""; 20     [HideInInspector][SerializeField] protected bool mLoop = true; 21     [HideInInspector][SerializeField] protected bool mSnap = true; 22  23     protected UISprite mSprite; 24     protected float mDelta = 0f; 25     protected int mIndex = 0; 26     protected bool mActive = true; 27     protected List<string> mSpriteNames = new List<string>(); 28  29     /// <summary> 30     /// Number of frames in the animation. 31     /// </summary> 32  33     public int frames { get { return mSpriteNames.Count; } } 34  35     /// <summary> 36     /// Animation framerate. 37     /// </summary> 38  39     public int framesPerSecond { get { return mFPS; } set { mFPS = value; } } 40  41     /// <summary> 42     /// Set the name prefix used to filter sprites from the atlas. 43     /// </summary> 44  45     public string namePrefix { get { return mPrefix; } set { if (mPrefix != value) { mPrefix = value; RebuildSpriteList(); } } } 46  47     /// <summary> 48     /// Set the animation to be looping or not 49     /// </summary> 50  51     public bool loop { get { return mLoop; } set { mLoop = value; } } 52  53     /// <summary> 54     /// Returns is the animation is still playing or not 55     /// </summary> 56  57     public bool isPlaying { get { return mActive; } } 58  59     /// <summary> 60     /// Rebuild the sprite list first thing. 61     /// </summary> 62  63     // 设置是否让图片显示原来大小还是按设置的大小进行缩放——vitah 64     public bool Snap 65     { 66         get 67         { 68             return this.mSnap; 69         } 70         set 71         { 72             this.mSnap = value; 73         } 74     } 75  76     protected virtual void Start ()  77     { 78         RebuildSpriteList(); } 79  80     /// <summary> 81     /// Advance the sprite animation process. 82     /// </summary> 83  84     protected virtual void Update () 85     { 86         if (mActive && mSpriteNames.Count > 1 && Application.isPlaying && mFPS > 0f) 87         { 88             mDelta += RealTime.deltaTime; 89             float rate = 1f / mFPS; 90  91             if (rate < mDelta) 92             { 93                  94                 mDelta = (rate > 0f) ? mDelta - rate : 0f; 95                 if (++mIndex >= mSpriteNames.Count) 96                 { 97                     mIndex = 0; 98                     mActive = loop; 99                 }100 101                 if (mActive)102                 {103                     mSprite.spriteName = mSpriteNames[mIndex];104                     if (mSnap)105                     {106                         mSprite.MakePixelPerfect();107                     }108                 }109             }110         }111     }112 113     /// <summary>114     /// Rebuild the sprite list after changing the sprite name.115     /// </summary>116 117     public void RebuildSpriteList ()118     {119         if (mSprite == null) mSprite = GetComponent<UISprite>();120         mSpriteNames.Clear();121 122         if (mSprite != null && mSprite.atlas != null)123         {124             List<UISpriteData> sprites = mSprite.atlas.spriteList;125 126             for (int i = 0, imax = sprites.Count; i < imax; ++i)127             {128                 UISpriteData sprite = sprites[i];129 130                 if (string.IsNullOrEmpty(mPrefix) || sprite.name.StartsWith(mPrefix))131                 {132                     mSpriteNames.Add(sprite.name);133                 }134             }135             mSpriteNames.Sort();136         }137     }138     139     /// <summary>140     /// Reset the animation to frame 0 and activate it.141     /// </summary>142     143     public void Reset()144     {145         mActive = true;146         mIndex = 0;147 148         if (mSprite != null && mSpriteNames.Count > 0)149         {150             mSprite.spriteName = mSpriteNames[mIndex];151             if (mSnap) mSprite.MakePixelPerfect();152         }153     }154 }
View Code

  新增的代码在63行位置,设置图片的大小是否更改的意思就是你导入的图片大小假定是600*100,但是你这时候sprite想显示的大小是300*100,假如不设置mSnap = false,NGUI会默认为true,这样每次播放动画的时候它会以图片的大小为显示大小,即最后显示在程序中的是600*100,设置mSnap = true;时,它就按你设定的大小进行缩放,最后显示的300*100的大小。

  

Unity NGUI实现序列帧动画播放