在ngui中如何动态加载图片。这里主要还是介绍如何利用UISprite来动态的加载图片。我们现在主要介绍2个方法。

      方法1: 

       直接在代码中创建和设置UIAtlas并对UISprite进行显示。这种方法可以对任何零散的贴图进行加载,但缺点是浪费DrawCall,主要应用在特别零散的贴图资源上。

public class ImageLoader : MonoBehaviour {
 //需要加载动态图片的对象
public UISprite m_img;
 //自用的Atlas
private UIAtlas m_uiAtlas;
 /// <summary>
/// 加载的贴图
/// </summary>
/// <param name="tex">Tex.</param>
public void ImageLoad(Texture2D tex)
{
if(tex == null)
{
return;
}
if(tex.name == m_img.spriteName)
{
return;
}
 //准备对象和材质球
if(m_uiAtlas == null)
{
Material mat;
Shader shader = Shader.Find("Unlit/Transparent Colored");
mat = new Material(shader);
m_uiAtlas = this.gameObject.AddComponent<UIAtlas>();
m_uiAtlas.spriteMaterial = mat;
}
 //设定贴图
m_uiAtlas.spriteMaterial.mainTexture = tex;
m_uiAtlas.coordinates = UIAtlas.Coordinates.Pixels;
 //为对应UISprite接口,给Atlas加对象 
UIAtlas.Sprite sprite = new UIAtlas.Sprite();
sprite.name = tex.name;
sprite.outer = sprite.inner = new Rect(0f, 0f, tex.width, tex.height);
m_uiAtlas.spriteList.Clear();
m_uiAtlas.spriteList.Add(sprite);
 //设置完成
m_img.atlas = m_uiAtlas;
m_img.spriteName = tex.name;
}

}

 方法2:

       将整个UIAtlas及其贴图打包,而后形成资源,驻留在内存中(仅仅是指向资源的指针),UNITY3D会根据引用来确定贴图是否直接放实际内存中。这种方法更适合ICON之类有规律可以配置整合的资源。缺点是需要维护。

 //从资源文件夹加载打包成assetBundle的ICON资源文件
private IEnumerator LoadResIcon()
{
 //准备好资源们
string strFormat = ResourcePath.GetPath() + "UI/{0}";
string strFilePath = "";
for(int i = 0 , nMax = GameConfig.Instance.IconSet.strIcons.Length; i < nMax ; i++)
{
string strAssetName = GameConfig.Instance.IconSet.strIcons;
strFilePath = string.Format(strFormat, strAssetName);
WWW tmp_www = null;
try
{
tmp_www = new WWW(strFilePath);
}
catch
{
tmp_www = null;
}
if(tmp_www==null)
{
continue;
}
yield return tmp_www;
if(tmp_www.error !=null)
{
tmp_www.Dispose();
tmp_www = null;
yield break;
}
AssetBundle tmp_assetBundle = tmp_www.assetBundle;
tmp_www.Dispose();
tmp_www = null;
UIAtlas atlas = tmp_assetBundle.Load(strAssetName,typeof(UIAtlas)) as UIAtlas;
tmp_assetBundle.Unload(false);
GameConfig.Instance.IconSet.SaveUIAtlas(i, atlas);
}
yield return null;

}

管理UIAtlas
public class IconSet
{
public string[] strIcons =
{
"A1_Atlas",
"A2_Atlas",
"A3_Atlas",
};
public UIAtlas[] m_AtlasData;
Dictionary<string, int> m_dicIcon;
public IconSet()
{
m_AtlasData = new UIAtlas[strIcons.Length];
m_dicIcon = new Dictionary<string, int>();
}
 //保存Atlas的完整信息
public void SaveUIAtlas(int nIndex, UIAtlas UIvalue)
{
m_AtlasData[nIndex] = UIvalue;
foreach (string iconNames in UIvalue.GetListOfSprites())
{
m_dicIcon[(string)iconNames.Clone()] = nIndex;//将所有的ICONNAME信息记录并且绑定成索引,以便查找
}
}
 //根据ICONNAME找出对应UIATLAS
public UIAtlas FindAtlasBySpriteName(string name)
{
int nAtlasIndex = 0;
if (m_dicIcon.TryGetValue(name, out nAtlasIndex))
{
return m_AtlasData[nAtlasIndex];
}
return null;
}
}
实际使用的范例:
 //设置显示对象
UISprite sprite = this.GetComponent<UISprite>();
sprite.atlas = GameConfig.Instance.IconSet.FindAtlasBySpriteName("Icon001");

sprite.spriteName = "Icon001";

 总结:
       以上两种方法基本能够应对大部分UI的现实问题,ImageLoader本身传入的是Texture2D,所以,即便是RenderTexture也没问题,都能与NGUI和谐相处。加以扩展的话,就是让另一个摄像机导出的东西和当前NGUI摆的UI结合。