UGUI_资源下载之Icon
说起icon相信大家都不陌生,如果是页游icon会做成动态下载,其实其他平台也是如此,需要单独给一组icon打包,然后游戏载入时根据类型和文件名加载图片。
如果你在学习UGUI相信也接触过NGUI,NGUI制作的图集作为prefab存在工程目录下,我们直接写打包工具就可以,而且游戏载入图集资源和显示时,在Game下也只是占用一个DrawCalls,这样挺好。
但是UGUI却不一样,合成之后的图集不会以文件的形式存在工程目录下,这时我们就不能和NGUI一样对一个parfab进行打包,是不是很纠结?但是我们还是必须给icon资源进行打包,如果单独给每一个icon打包,那么载入资源显示时,一个icon就占用一个DrawCalls,这样明显不可取。所以我们可以把一组icon打包为一个文件,比如使用BuildAssetBundle的第二个参数存放一组icon。
BuildPipeline.BuildAssetBundle(null,assets.ToArray(),targetPath,BuildAssetBundleOptions.CollectDependencies,
BuildTarget.StandaloneWindows);
将打包icon到界面显示icon的流程简单分为四步:
1.打包icon资源为unity3d文件
将一组icon资源导入unity,设置为同一个图集。
关于后缀名可能大家都是保存为.assetbundle,这个其实可以自定义,但是我觉得.unity3d更拉风!
代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;
[ExecuteInEditMode]
public class ExportIcon : MonoBehaviour
{
private static string m_u3dPath = Application.dataPath + "/data/ui/icon";
private static string m_u3dName = "";
[MenuItem("Assets/ExportU3DByIcon")]
static public void ExpoerIconU3D()
{
GetIconDirectory();
}
// 获取icon目录
static private void GetIconDirectory()
{
// 获取当前选中的icon文件夹
string iconDirectory = "";
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
for (int i = 0; i < selection.Length; i++)
{
if (selection[i].name.Contains("icon_"))
{
iconDirectory = AssetDatabase.GetAssetPath(selection[i]);
iconDirectory = iconDirectory.Replace("Assets/", "");// 去掉一个Assets
m_u3dName = selection[i].name;
break;
}
}
if (iconDirectory.Equals(""))
{
EditorUtility.DisplayDialog("导出错误", "当前目录不为icon目录", "确定");
return;
}
iconDirectory = Application.dataPath + "/" + iconDirectory;
BuildU3D(iconDirectory);
}
// 打包为U3D文件
static private void BuildU3D(string prefabDirectory)
{
List assets = new List();
DirectoryInfo rootDirInfo = new DirectoryInfo(prefabDirectory);
foreach (FileInfo fileInfo in rootDirInfo.GetFiles())
{
if (fileInfo.Name.Contains(".png") && !fileInfo.Name.Contains(".meta"))
{
string assetPath = fileInfo.FullName.Substring(fileInfo.FullName.IndexOf("Assets"));
Sprite sprite = Resources.LoadAssetAtPath(assetPath);
assets.Add(sprite);
}
}
Directory.CreateDirectory(m_u3dPath);
string targetPath = m_u3dPath + "/" + m_u3dName + ".unity3d";
BuildPipeline.BuildAssetBundle(null, assets.ToArray(), targetPath, BuildAssetBundleOptions.CollectDependencies,
BuildTarget.StandaloneWindows);
}
}
2.下载icon资源
(ResourceFactory在这里就不公开了,这个封装了资源下载功能)
public class LoadIcon
{
private int m_resId = 0;
private string m_imageName = "";
private Image m_image = null;
private static Dictionary<</SPAN>int, AssetBundle> m_iconMap = new Dictionary<</SPAN>int, AssetBundle>();
public void Load(int resId, string name, Image image)
{
m_resId = resId;
m_imageName = name;
m_image = image;
if (!m_iconMap.ContainsKey(m_resId))
{
ResInfo resInfo = ResCsvInfo.GetResInfo(2);
ResourceFactory.Inst.LoadResource(resInfo, LoadEnd, null);
}
else
{
image.sprite = m_iconMap[m_resId].Load(name) as Sprite;
}
}
private void LoadEnd(Resource res)
{
m_iconMap.Add(m_resId, res.m_assertBundle);
m_image.sprite = m_iconMap[m_resId].Load(m_imageName) as Sprite;
}
}
3.UI层封装界面
public Transform m_list;
public GameObject m_item;
private void UpdateImageList(int index,string image)
{
Transform item = ((GameObject)GameObject.Instantiate(m_item)).transform;
item.gameObject.SetActive(true);
item.name = index.ToString();
item.SetParent(m_list);
LoadIcon icon = new LoadIcon();
icon.Load(2, image, item.GetComponent());
}
4.逻辑层开始读配置表拿到icon名称,直接调用UI的接口即可!
List imageList = new List()
{
"129001","129007","129017","129025","129026","129035"
};
for (int i = 0; i < imageList.Count; i ++)
{
UpdateImageList(i, imageList[i]);
}
最后界面显示如下:
再看看DrawCalls:
(2个,就对了!这些图标只会暂用一个DrawCall)