说起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]); - }
最后界面显示如下:
(2个,就对了!这些图标只会暂用一个DrawCall)
本文介绍如何在Unity中使用UGUI进行Icon资源的批量打包,并实现资源的有效加载及显示,以减少DrawCalls数量,提升游戏性能。


764

被折叠的 条评论
为什么被折叠?



