ok, 之前写了一个3D模型的动画设置, 想看的可以翻我的博客。 下面我写一个动画序列帧的文章, 我所写的文章,大部分都是来自于工作中遇到的问题 。 问题是这样的, 一个新毕业的学生,给公司写了一个项目,其中 一个动物的展示动作他用来动画序列帧来做的。一整套动作一共有600个图片, 是的,你没看错, 600个图片, 更可怕都是,里面有十几个动画, 有个动画有900 个图片, 然后呢,这个学生在开始界面一下子把这些动画加入内存中,虽然做了进度条, 然后呢 这个项目大家都知道结果是GG了, 加载到一半时候,内存就爆掉了。 怎么能这样做项目。 那么我们应该怎么做呢, 其实很简单了。 那就是我们在用到哪里的时候就去加载那里。 比如说,第一个场景用到的动画那就再第一个场景开始前加载。 先说下第一个方案 代码如下:
using UnityEngine;
class FrameAnimation
{
public float fps =100.0f;
private Rect drawPos;
Texture frameAniTex;
private float time = 0;
private int currentIndex = 0;
private Rect frameAnimPos = new Rect(0, 0, Screen.width, Screen.height);
int length = 600;
public void DrawFrameAnimation(Texture[] frameTex)
{
int length = frameTex.Length;
GUI.DrawTexture(drawPos, frameTex[currentIndex]);
time += Time.deltaTime;
if (time >= 1.0f / fps)
{
currentIndex++;
time = 0;
if (currentIndex >= length - 1)
{
//停止动画
currentIndex = length - 1;
}
}
}
//构造函数
public FrameAnimation(Rect drawPos, float fps)
{
this.drawPos = drawPos;
this.fps = fps;
}
}
这个类是我从网上找到代码,然后我做了修改。 其实原理很简单,就是用GUI 去绘制每一个图片, fps 是控制图片更新速度的。
调用方法如下:
using UnityEngine;
using System.Collections;
public class DrawPicture : MonoBehaviour
{
//private Resources resource;
private Rect drawPos = new Rect(0, 0, Screen.width, Screen.height);
private Object[] texObject;
public bool isCanDraw = false;
private string path;
Texture[] frameTex;
private FrameAnimation frameAni;
// Use this for initialization
void Start()
{
//一次性加载所有的序列帧图片
LoadTexture(texObject, "FrameTex");
frameAni = new FrameAnimation(drawPos, 100);
}
void OnGUI()
{
frameAni.DrawFrameAnimation(frameTex);
}
void LoadTexture(Object[] texObj, string path)
{
texObj = Resources.LoadAll(path);
frameTex = new Texture[texObj.Length];
texObj.CopyTo(frameTex, 0);
}
}
这样 呢, 是可以减少些内存的消耗, 但是还不够完美, 我们做事就要追求完美, 不要总是认为自己是写代码的, 做游戏做的是艺术。
那么怎么样做更好, 那就是我们在现实哪张图片的时候,再去加载那张图片,这样才是最好的。我们只要把代码稍微改下就好了
using UnityEngine;
class FrameAnimation
{
public float fps =100.0f;
private Rect drawPos;
Texture frameAniTex;
private float time = 0;
private int currentIndex = 0;
private Rect frameAnimPos = new Rect(0, 0, Screen.width, Screen.height);
int length = 600;
public void DrawFrameAnimation(Texture[] frameTex)
{
int length = frameTex.Length;
GUI.DrawTexture(drawPos, frameTex[currentIndex]);
time += Time.deltaTime;
if (time >= 1.0f / fps)
{
currentIndex++;
time = 0;
if (currentIndex >= length - 1)
{
currentIndex = length - 1;
}
}
}
public void FrameAnimation2()
{
//每次用到哪张图片再去加载哪张图片
frameAniTex = Resources.Load("FrameTex/Lion_FX_2_" + currentIndex.ToString("D5")) as Texture;
//显示图片
GUI.DrawTexture(frameAnimPos, frameAniTex);
if (currentIndex < length - 1)
{
time += Time.deltaTime;
if (time >= 1.0f / fps)
{
currentIndex++;
time = 0;
if (currentIndex == length - 1)
{
Resources.UnloadUnusedAssets();
}
}
}
}
public FrameAnimation(Rect drawPos, float fps)
{
this.drawPos = drawPos;
this.fps = fps;
}
}
调用的时候 去掉全部加载图片的代码, 然后再OnGUI 中调用
FrameAnimation2 这样就不会一下子加入很多图片导致卡顿了。