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的大小。

  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。