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();
        }
    }
}

更改后的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 }

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

  

时间: 2024-11-08 08:55:18

Unity NGUI实现序列帧动画播放的相关文章

关于在unity中使用序列帧动画

//动画数组 public object[] anim; //限制一秒多少帧 public float fps = 30; //帧序列 private int nowFram; //记录当前时间 private float switchTime; public string path = "Texture/33"; public bool isLoop = false; public Image image; public Texture2D texture; void Awake()

unity shader序列帧动画代码,顺便吐槽一下unity shader系统

http://www.cnblogs.com/hellohuan/archive/2014/01/10/3512784.html 一.看到UNITY论坛里有些人求unity shader序列帧动画,写shader我擅长啊,就顺势写了个CG的shader.代码很简单,就是变换UV采样序列帧贴图,美术配置行数列数以及变换速度. Shader "HELLOHUAN/Hello_Sequence" { Properties { _Color ("Main Color", C

【Unity NGUI游戏开发之三】TweenPosition位移动画(二):相对于UIAnchor不同分辨率下的完美适配位移动画

Unity中的UI我们采用的是NGUI,NGUI的界面位移动画,我们一般使用的是TweenPosition. 一种是简单的相对位移,不考虑分辨率适配问题,只需要简单的从位置A到位置B,已经在文中介绍了: [Unity NGUI游戏开发之二]TweenPosition位移动画(一):不相对于Anchor的位移动画 另外一种是考虑到屏幕分辨率适配的位移动画,我们游戏中大多遇到的是这种情况. eg.我们想让一个UI从屏幕外沿着屏幕的左边移动到屏幕的中央,TweenPositon播放动画,在960*64

【Unity NGUI游戏开发之六】游戏背景采用UV纹理动画

开发背景 游戏中一些背景能采用UV动画,效果更佳.eg.星空.墙壁 因为gif的原因有卡顿,起始播放纹理动画的时候是不会有卡顿的. Unity的NGUI采用纹理动画 NGUI的UITexture允许使用一张纹理 有了这个,我们便可以扩展一个脚本来影响[UV Rect]参数了 /** 基于NGUI的UITexture的纹理动画 1.图片首尾相接的UITexture,可以播放UV纹理动画 2.可以根据定制UV动画方向.速度 3.图片属性: [Texture Type]:Texture [Wrap M

关于unity中spine动画切换时有残影或者动画播放不正确的解决方法

问题描述: 最近在用spine动画时发现,有时候角色在切换动画的时候会有残影,或者动画播放不正确,例如会丢失一部分节点,例如切换动画后角色虽然动画播放正常,但丢失了武器. 解决办法: 在unity编辑器下找到spine动画的SkeletonData文件,在Animationgs下面有一个"Setup Pos",这个按钮可以将骨骼(bones).资源槽(slots)或两者重置为装配动作(setup pose).它与调用`setBonesToSetupPose` 或 `setSlotsTo

Unity3D中播放序列帧动画

[狗刨学习网] class FrameAnimation { private float fps = 10.0f; private Rect drawPos; private float time = 0; private int currentIndex = 0; public void DrawFrameAnimation(Texture[] frameTex) { int length = frameTex.Length; GUI.DrawTexture(drawPos, frameTex

【Unity NGUI游戏开发之二】TweenPosition位移动画(一):不相对于Anchor的位移动画

下面学些下NGUI的TweenPosition位移动画,一般的位移动画需求分为不想对于Anchor锚点的位移动画和相对于Anchor的位移动画(主要看是否考虑屏幕分辨率),下面介绍两种游戏中最常用的不相对于Anchor的TweenPosition用法: 用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画 用法2.在游戏中需要动态创建带有TweenPosition组件动画的对象,对象创建.移动.到达指定位置.销毁的过程.eg.游戏中玩家吃金币,迟到金币后转换为分数,分数播放一个Twe

quick cocos2dx 播放序列帧动画的实现

本帖基于quick cocos2dx2.2.6版本. 序列帧动画:顾名思义就是在一定的时间内播放多张图片. 基本原理非常简单,在一个固定的位置1秒时间内轮询播放有限数量的不同图片.比如1秒中播放24张图(FPS=24) 在quick引擎中可以通过framwork中的transition.lua文件中得transition.playAnimationForever(target, animation, delay)接口来实现动画的播放,其源码如下: function transition.play

Cocos2d-x动画播放(序列帧)

简介 Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果.动画由帧组成,每一帧都是一个纹理,我们可以使用一个纹理序列来创建动画. 我们使用Animation类描述一个动画,而精灵显示动画的动作则是一个Animate对象.动画动作Animate是精灵显示动画的动作,动画与动画动作的关系如同CD光盘与CD播放机的关系,前者记录了动画的内容,后者是播放动画的工具,它由一个动画对象创建,并由精灵执行.