最近項(xiàng)目中用到了很多序列幀動(dòng)畫紊馏,之前看教程也接觸過序列幀動(dòng)畫硬贯,但當(dāng)時(shí)沒用到,就沒仔細(xì)研究掸驱,這次就借著這個(gè)機(jī)會(huì)好好總結(jié)一下序列幀動(dòng)畫窘哈。
思路
序列幀動(dòng)畫的原理很好理解,首先必須要有一個(gè)載體亭敢,一般是一個(gè)圖片滚婉,然后申請(qǐng)一個(gè)數(shù)組或List<sprite>用來存放序列幀,然后再根據(jù)需要遍歷這個(gè)數(shù)組替換載體的圖片源帅刀,這樣就實(shí)現(xiàn)動(dòng)畫效果了让腹。
代碼
public class Anim : MonoBehaviour {
public float animSpeed = 10; //動(dòng)畫播放速度 默認(rèn)1秒播放10幀圖片
private float animTimeInterval = 0; //幀與幀間隔的時(shí)間
public SpriteRenderer animRenderer;//動(dòng)畫載體的渲染器
public Sprite[] SpriteArray; //序列幀數(shù)組
private int frameIndex = 0; //幀索引
private int animLength = 0; //多少幀
private float animTimer = 0; //動(dòng)畫時(shí)間計(jì)時(shí)器
// Use this for initialization
void Start () {
animTimeInterval = 1 / animSpeed;//得到每一幀的時(shí)間間隔
animLength = SpriteArray.Length; //得到幀數(shù)
}
// Update is called once per frame
void Update()
{
animTimer += Time.deltaTime;
if (animTimer > animTimeInterval)
{
animTimer -= animTimeInterval;//當(dāng)計(jì)時(shí)器減去一個(gè)周期的時(shí)間
frameIndex++;//當(dāng)幀數(shù)自增(播放下一幀)
frameIndex %= animLength;//判斷是否到達(dá)最大幀數(shù),到了就從新開始 這里是循環(huán)播放的
animRenderer.sprite = SpriteArray[frameIndex]; //替換圖片實(shí)現(xiàn)動(dòng)畫
}
}
}
其他形式
基于上面的代碼還可以添加一些其他動(dòng)畫的功能扣溺,比如暫停/停止(添加bool變量骇窍,Pause方法內(nèi)判斷是否暫停)快進(jìn)慢進(jìn)(方法內(nèi)調(diào)節(jié)每秒播放的幀數(shù))主要通過對(duì)這個(gè)類變量的控制來實(shí)現(xiàn)的,NGUI里有SpriteAnimation锥余,UI SpriteAnimation等內(nèi)置的序列幀動(dòng)畫腳本腹纳,里面的序列幀動(dòng)畫的功能比較全,有感興趣的可以去看下NGUI的源碼驱犹。
除了spriterenderer嘲恍,texturerenderer和ui sprite也可以實(shí)現(xiàn)序列幀動(dòng)畫,效果差不多
一些思考
在最近項(xiàng)目中遇到的序列幀動(dòng)畫是全屏的雄驹,圖片都很大佃牛,第一次加載時(shí)非常卡医舆,這個(gè)問題后來通過兩個(gè)途徑解決的俘侠,在這里說一下
-
在可以接受的情況下降低畫質(zhì)
如圖,調(diào)節(jié)MaxSize屬性能控制畫質(zhì)蔬将,縮小圖片的大小
-
分割序列幀數(shù)組
因?yàn)樾蛄袔诓シ徘靶枰燃虞d進(jìn)數(shù)組里面爷速,圖片多了內(nèi)存占用過大就很卡,因此可以優(yōu)化資源加載算法實(shí)現(xiàn)分階段加載視頻霞怀,具體代碼就不寫了惫东,這里我說一下思路:有500幀圖片,不要一次加載完里烦,100幀100幀的加載凿蒜,第一個(gè)100幀播放到50幀的時(shí)候開始加載第二個(gè)100幀,以此類推胁黑,這樣就分散了對(duì)系統(tǒng)資源的占用废封,響應(yīng)的會(huì)流暢一些。