unity 动态打atlas图集

NGUI提供了很方便的UIAtlas,其主要作用是改进DrawCall,把众多图片整合在一张贴图上,由于简单易用的好处,所以只是用原生的GUI很容易忽视DrawCall的 问题 ,所以NGUI为了改进,才有了UIAtlas。当然NGUI还做了很多优化。

  这里主要还是介绍如何利用UISprite来动态的加载图片。NGUI所提供的UIAtlas虽然好用,但只能在Editor内生成贴图和prefab以供UISprite使用。为了能够让游戏资源与游戏本体尽可能的分离,特别是游戏资源需要动态更新的情况。很多时候,都需要动态加载,动态设置UIAtlas。

  这里主要介绍2个方法。

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

[AppleScript]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42


public class ImageLoader : MonoBehaviour {
/ / 需要加载动态图片的对象
public UISprite m_img;
/ / 自用的Atlas
private UIAtlas m_uiAtlas;
/ / / <s ummary >
/ / / 加载的贴图
/ / / < / summary >
/ / / < param name = “tex” > Tex. < / param >
public void ImageLoad ( Texture 2 D 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 ( 0 f , 0 f , 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之类有规律可以配置整合的资源。缺点是需要维护。

[AppleScript]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

/ / 从资源文件夹加载打包成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[i];
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
[AppleScript]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

public class IconSet
   {
  public string [] strIcons =
   {
  “A 1 _Atlas” ,
  “A 2 _Atlas” ,
  “A 3 _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 ( “Icon 001 ) ;
  sprite.spriteName = “Icon 001 ”;


  总结:

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

猜你喜欢

转载自blog.csdn.net/lalate/article/details/68066049