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