`

NGUI所见即所得之UIAtlasMaker , UIAtlas

阅读更多

     NGUI所见即所得之UIAtlasMaker , UIAtlas

 

        本文的重点就是要将NGUI把多张图片打成一个图集(Atlas)的原理和过程研究下,学习下Unity提供的api和NGUI写的功能以及设计思想。

 

UIAtlas

       在介绍UIAtlasMaker之前先看下,先看下UIAtlasMaker的产物——UIAtlas,在创建Sprite的时候都要指定UIAtlas,下面先对UIAtlas的代码:

        // Material used by this atlas. Name is kept only for backwards compatibility, it used to be public.
	[HideInInspector][SerializeField] Material material;

	// List of all sprites inside the atlas. Name is kept only for backwards compatibility, it used to be public.
	[HideInInspector][SerializeField] List<UISpriteData> mSprites = new List<UISpriteData>();

	// Size in pixels for the sake of MakePixelPerfect functions.
	[HideInInspector][SerializeField] float mPixelSize = 1f;

	// Replacement atlas can be used to completely bypass this atlas, pulling the data from another one instead.
	[HideInInspector][SerializeField] UIAtlas mReplacement;

        // Whether the atlas is using a pre-multiplied alpha material. -1 = not checked. 0 = no. 1 = yes.
	int mPMA = -1;

      可以很惊奇的发现UIAtlas的成员变量竟然极其精简,就只有:Material material;      UISpriteDatat的List mSprites;      每个像素的大小 mPixelSize 这个跟UIWidget的像素大小应该是类似的,  UIAtlas mReplacement; 这个目前只能望文生义,虽然知道是用来替换UIAtlas,但好像没有发现哪里会有用到,在UISprite的那里只是选择不同的UIAtlas而不是替换UIAtlas本身,就暂且搁置,   最后一个是mPMA这个是pre-multiplied的像素存储技术,大致了解下,好像是把alpha的值存储在每个颜色的RGB中去已达到节省存储空间的技术,想要了解更多可以自行google下。

      接着看UIAtlas,接下来就是把属性的{get,set} 以及几个函数,也很简单,主要就是属性改变,就调用MakeAsDirty()函数,下面看下这个函数的前面一部分:

public void MarkAsDirty ()
	{
#if UNITY_EDITOR
		UnityEditor.EditorUtility.SetDirty(gameObject);
#endif
		if (mReplacement != null) mReplacement.MarkAsDirty();

		UISprite[] list = NGUITools.FindActive<UISprite>();

		for (int i = 0, imax = list.Length; i < imax; ++i)
		{
			UISprite sp = list[i];

			if (CheckIfRelated(this, sp.atlas))
			{
				UIAtlas atl = sp.atlas;
				sp.atlas = null;
				sp.atlas = atl;
#if UNITY_EDITOR
				UnityEditor.EditorUtility.SetDirty(sp);
#endif
			}
		}
            ……
        }

 可以看出这个函数其实就是更新以replacemet和this为UIAtlas的UISprite的UIAtlas,就是这么简单。

 

 UISpriteData

       在UIAtlas中有GetSprite()和GetListOfSprites(),其中GetSprite返回的UISpriteData,让人不得不猜想UISpriteData就是UISprite中的图片,但其实它只是一个结构体:

public class UISpriteData
{
	public string name = "Sprite";
	public int x = 0;
	public int y = 0;
	public int width = 0;
	public int height = 0;

	public int borderLeft = 0;
	public int borderRight = 0;
	public int borderTop = 0;
	public int borderBottom = 0;

	public int paddingLeft = 0;
	public int paddingRight = 0;
	public int paddingTop = 0;
	public int paddingBottom = 0;

       一看这些成员变量,就会感觉很熟悉,这不是就是UI组件的基本熟悉么,可以进一步看下UIInspectorEditor界面,就更加确信了,而且Border其实用在SliceSprite的,至于Padding就是空白不显示区域,而且x,y,width,height其实该图片就是在UIAtlas上Rect区域。

 

      也就是说,UISpriteData根本没有实际记录图片的像素信息,而只是记录图片在UIAtlas生成的那张大图的坐标,宽度和高度,以及图片拉伸的一些信息(Border,Padding)。

 

UIAtlasMaker

      从前面的分析,可以大概知道UIAtlasMaker的原理:把多张图片合并成一张大图,记录每张图片的在生成的大图的坐标和大小。下面将使用介绍算法那种思路把UIAtlasMakder的工作流程描述清楚。

      在详细介绍之前,UIAtlasMakder定义了UISpriteEntry这个类:

class SpriteEntry : UISpriteData
	{
		// Sprite texture -- original texture or a temporary texture
		public Texture2D tex;
		
		// Whether the texture is temporary and should be deleted
		public bool temporaryTexture = false;
	}

       只是在UISpriteData基础上扩展了一个Texture2D tex的成员变量,那么这个类到底做什么用呢?通过分析代码可以知道:UISpriteEntry是UISpriteData和Texture2D的中间体,是Texture2D和UISpriteData转化的载体,就提过程下面会有引人。

 

 

UIAtlasMaker的工作流程:

1)选择图片or图集,函数:void OnSelectAtlas (Object obj) 和 List<Texture> GetSelectedTextures ()

2)导入选择图片的Texture2D,函数:static List<Texture2D> LoadTextures (List<Texture> textures)

3)将Texture2D转出UISpriteEntry,函数:static List<SpriteEntry> CreateSprites (List<Texture> textures) ,这个函数中包括了2)的步骤

3)打包成大图片并生成UISpriteData,函数:static bool PackTextures (Texture2D tex, List<SpriteEntry> sprites),这个函数提供两种打包方式:1.NGUI自己实现类UITextPacker,2.Unity3D提供的api

4)释放UISpriteEntry,函数:static void ReleaseSprites (List<SpriteEntry> sprites),主要是通过NGUITools.Destroy销毁纹理,最后调用Resources.UnloadUnusedAssets();,这个趁机告诉我们Unity中资源销毁的方法,一个不能少哈。

static void ReleaseSprites (List<SpriteEntry> sprites)
	{
		foreach (SpriteEntry se in sprites)
		{
			if (se.temporaryTexture)
			{
				NGUITools.Destroy(se.tex);
				se.tex = null;
			}
		}
		Resources.UnloadUnusedAssets();
	}

 

差不多就是这样子,其他就是一些功能操作:add,replace,delete,udpate,extract。

 

       这样看来,把UIAtlas分析清楚,掌握UIAtlasMaker的原理应该不难,当然里面有很多细节,使用很多api:AssetDatabase,Texture,SelectedObject以及NGUI自己封装的一些函数。

 

 

小结:

       UIAtlas虽然在使用NGUI过程中用的太多了,但是经过上面的分析,其实不是很难,个人觉得还没有UIRoot(NGUI所见即所得之UIRoot)的难以驾驭,即使UIRoot很短很单一。这里说下D.S.Qiu的关于快速学习的一点体会:古人有云,“工欲善其事,必先利其器”,NGUI最为一个工具,要使用好它,就要充分掌握它, 换句话说就要懂它,当然还可以从中偷到很多师——功能的具体实现和代码逻辑的设计,其实一直觉得我对细节都不求甚解,会用就可以走路了,又不用自己写一个NGUI,当然细节都能掌握就更完美了。已经到凌晨一点了,先写这么多,有补充在加。

         如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。

        转载请在文首注明出处:http://dsqiu.iteye.com/blog/1967088

更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)

 

 

 

 

  • 大小: 59.6 KB
3
0
分享到:
评论
1 楼 cj_zzu 2014-02-11  
非常感谢分享

相关推荐

    NGUI插件3.11.2版本

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。 基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。 全面支持iOS/Android和Flash。 灵活的事件系统。 可以让...

    CustomGUI.unitypackage

    使用unity原生GUI封装,来达到UGUI,NGUI所见即所得的效果和部分功能,目的是由此来了解高级UI的原理。

    NGUI_3.11.3.unitypackage

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。 基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。 全面支持iOS/Android和Flash。 灵活的事件系统。 可以让...

    NGUI3.11.4

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。 基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。 全面支持iOS/Android和Flash。 灵活的事件系统。 可以让...

    NGUI 2019_3_0.unitypackage.zip

    开发者可以在Unity编辑器中直接设计和调整UI元素,实现所见即所得的效果。这种设计方式极大地提高了开发效率,使得UI设计和游戏逻辑的开发可以同步进行,减少了开发者在不同工具间切换的时间成本。 二、本地化与...

    NGUI Next-Gen UI 2020.1.5

    - 编辑器集成,所见即所得 - 本地化、数据绑定、委托、事件 - 支持所有平台 - 制作进行 1 次绘制调用的 UI - 随附完整的 C# 源代码 - 已广泛优化 - 专门团队支持 2020.1.5 - NEW: You can now specify per-symbol ...

    NGUI插件大全

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。 基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。 全面支持iOS/Android和Flash。 灵活的事件系统。 可以让...

    NGUI3.6.4 最新版本NGUI ngui

    《NGUI 3.6.4:打造高效Unity3D移动界面的利器》 NGUI,全称为Next-Gen UI,是Unity3D游戏引擎中的一款广泛应用的界面系统插件,尤其在移动游戏开发领域备受青睐。其3.6.4版本作为官方发布的最新版,不仅集成了之前...

    NGUI 3.5.9

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。  基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。  全面支持iOS/Android和Flash。  灵活的事件系统。...

    最新版本的NGUI插件NGUI Next-Gen UI 覆盖unity多个版本

    NGUI Next-Gen UI是一款功能强大、灵活性高的UI插件,是当前最新版本的NGUI插件。它可以覆盖Unity的多个版本,包括Unity 5、Unity 2017和Unity 2018等。与其他UI插件相比,NGUI Next-Gen UI具有高效的性能和优秀的...

    NGUI 2020.1.5.unitypackage

    NGUI 是一款非常强大的 UI 系统和事件通知框架。...- 编辑器集成,所见即所得 - 本地化、数据绑定、委托、事件 - 支持所有平台 - 制作进行 1 次绘制调用的 UI - 随附完整的 C# 源代码 - 已广泛优化 - 专门团队支持

    NGUI3.5.9 Unity3d UI开发神器

    在场景视图中看到的就是在游戏视图中得到的(所见即所得)。  基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加相应的行为,而不需要编码。  全面支持iOS/Android和Flash。  灵活的事件系统。...

    NGUI3.7.3unitypackage

    NGUI3.7.3unitypackage 是 NGUI 的一个特定版本,即3.7.3版的资源包。这个版本包含了对 NGUI 系统的更新和改进,旨在提升性能、优化用户体验以及增加新的功能。 NGUI 的核心特性包括: 1. **Widget 系统**:NGUI ...

    NGUI v3.12.1 2018 最新版NGUI

    《NGUI v3.12.1:2018年Unity UI系统深度解析》 NGUI,全称为Next-Gen UI,是一款专为Unity引擎设计的用户界面系统。在2018年,它发布了v3.12.1的最新版本,此更新旨在优化用户体验,提升性能,并增加新功能。作为...

    NGUI练习项目源码

    再者,NGUI的UIAtlas是管理纹理资源的组件,它可以将多个小图片打包成一个大图,减少内存占用和加载时间。在项目源码中,我们能看到UIAtlas的配置和引用,以及如何在Widget中使用这些纹理。 此外,UIPanel是NGUI...

    NGUI3.11.2

    NGUI 是一个针对 Unity 游戏引擎的用户界面(UI)系统,专为游戏开发者设计,提供了一套高效、易用且功能丰富的UI组件。在3.11.2版本中,NGUI 进一步提升了性能和用户体验,遵循了“Keep It Simple, Stupid”(KISS...

    ngui 3.7.0

    《NGUI 3.7.0:Unity开发插件的深度解析与应用指南》 NGUI,全称为Next-Gen User Interface,是一款专为Unity3D游戏引擎设计的UI开发插件,它提供了丰富的界面元素和强大的交互功能,极大地简化了开发者在创建用户...

    Unity插件 NGUI各种版本合集

    本包中共有六个版本的NGUI,大家可以自己选择版本。 NGUI Next-Gen UI 3.6.0.unitypackage NGUI Next-Gen UI 3.12.1(u5.6.5).unitypackage NGUI Next-Gen UI 2019.3.0.unitypackage NGUI Next-Gen UI v2018.3.0....

    NGUI离线文档

    NGUI离线文档是针对Unity游戏开发中NGUI框架的一个详细参考资料,主要基于3.7.5版本。NGUI是一个用户界面系统,专为Unity3D设计,它提供了丰富的UI组件和工具,使得开发者能够在2D和3D环境中创建出交互性强、视觉...

    NGUI-Unity(2020-2021)亲测可用

    《NGUI在Unity中的应用详解》 Unity,作为全球领先的实时3D内容创作和运营平台,深受游戏开发者和视觉效果创作者的喜爱。而NGUI(Next Generation User Interface)是Unity早期流行的一款用户界面(UI)系统插件,...

Global site tag (gtag.js) - Google Analytics