前一段在做一個(gè)功能的時(shí)候必須加載外部多張連續(xù)的圖片吃警,來實(shí)現(xiàn)一個(gè)簡單的小動畫唧躲。本來是一個(gè)非常簡單的功能许起,不用兩分鐘就寫好了岗宣。但是最終打成apk測試的時(shí)候有個(gè)非常大的問題就是非陈祝卡转捕,圖片播放卡的簡直不忍直視,后來去看unity的官方文檔唆垃,發(fā)現(xiàn)了一個(gè)非常好用的方法五芝。
我們在使用unity的UGUI中的圖片的時(shí)候,絕大多數(shù)人都是使用Image這個(gè)組件辕万,而大家基本上很容易忽略掉這個(gè)組件的使用效率問題枢步,因?yàn)槎际窃趗nity創(chuàng)建好的sprite直接賦值所以 看不出來有什么問題,但是如果你是直接動態(tài)加載外部的或者下載的圖片你就會發(fā)現(xiàn)加載的時(shí)候特別卡渐尿,特別是越大醉途,越不規(guī)則的圖片更是耗時(shí)。但是還有個(gè)被大家忽略的組件就是RawImage砖茸,這個(gè)組件可以說是Image的簡化版隘擎,它的功能雖然少很多但是幾個(gè)基本的功能都在,最主要的是它可以直接賦值texture圖片凉夯,這里大家可以不是很清楚货葬,所以沒有什么比直接寫代碼更直接的方式了:
public void ImageAssignment() //Image組件賦值方法
{
var path = Application.streamingAssetsPath + "/icon.png"; //外部圖片地址
var tex = ResLoader.DownloadSync(path).texture; //使用www加載外部圖片(這個(gè)方法是自己寫的采幌, 不會的話自己上網(wǎng)百度下)
var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
ImageObject.sprite = sprite;
}
public void RawImageAssignment() //RawImage組件賦值方法
{
var path = Application.streamingAssetsPath + "/icon.png"; //外部圖片地址
var tex = ResLoader.DownloadSync(path).texture; //使用www加載外部圖片(這個(gè)方法是自己寫的, 不會的話自己上網(wǎng)百度下)
RawImageObject.texture = tex;
}
有什么發(fā)現(xiàn)么震桶?使用RawImage加載外部圖片是不是直接少了一行代碼休傍,然道僅僅只是一行代碼那么簡單么?接下來尼夺,我再給大家看一下我做的幾個(gè)加載時(shí)間的對比:
1尊残、512512圖片兩種方式 賦值100次的對比
image.png
2、1024512圖片兩種方式 賦值100次的對比
image.png
3/1112*900圖片兩種方式 賦值100次的對比
image.png
看了這些數(shù)據(jù) 你會發(fā)現(xiàn)我說的 提高百倍以上的效率真的是一點(diǎn)都不夸張啊淤堵。
這里可以看到使用RawImage 不管加載什么分辨率的圖片 效率都是基本 差不多快到可以忽略不計(jì)寝衫,而使用Image卻是會因?yàn)閳D片的分辨率大受影響。主要的原因就是在創(chuàng)建sprite這一步特別耗時(shí)拐邪,而且圖片越大慰毅、越不規(guī)則就會越耗時(shí)。所以你應(yīng)該知道怎么做了吧扎阶!
最后貼上代碼 供大家參考汹胃,互相學(xué)習(xí)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using Babybus.Uno;
public class TestImageLoad : MonoBehaviour
{
public Image ImageObject;
public RawImage RawImageObject;
public void OnClickImageButton() //Image組件賦值方法
{
var path = Application.streamingAssetsPath + "/icon.png";//外部圖片地址
var tex = ResLoader.DownloadSync(path).texture;//使用www加載外部圖片(這個(gè)方法是自己寫的, 不會的話自己上網(wǎng)百度下)
var time = Time.realtimeSinceStartup;
for (var i = 0; i < 100; i++)
{
var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
ImageObject.sprite = sprite;
}
Debug.Log("Image賦值100次使用時(shí)間: " + (Time.realtimeSinceStartup-time));
}
public void OnClickRawImageButton()//RawImage組件賦值方法
{
var path = Application.streamingAssetsPath + "/icon.png";//外部圖片地址
var tex = ResLoader.DownloadSync(path).texture;//使用www加載外部圖片(這個(gè)方法是自己寫的东臀, 不會的話自己上網(wǎng)百度下)
var time = Time.realtimeSinceStartup;
for (var i = 0; i < 100; i++)
RawImageObject.texture = tex;
Debug.Log("RawImage賦值100次使用時(shí)間: " + (Time.realtimeSinceStartup - time));
}
}
using System;
using System.Collections;
using UnityEngine;
namespace Babybus.Uno
{
public static class ResLoader
{
public static WWW DownloadSync(string path, WWWForm form = null)
{
WWW www;
if (form != null)
www = new WWW(path.ToWWWUrl(), form);
else
www = new WWW(path.ToWWWUrl());
YieldToStop(www);
return www;
}
private static void YieldToStop(WWW www)
{
var @enum = DownloadEnumerator(www);
while (@enum.MoveNext()) ;
}
private static IEnumerator DownloadEnumerator(WWW www)
{
while (!www.isDone) ;
yield return www;
}
}
}