【Unity3D】【NGUI】Atlas的动态创建

本文介绍了如何在Unity3D中使用NGUI动态创建Atlas,适用于需要从网络下载图片并避免使用UITexture的情况。文章提供了一份SZUIAtlasMakerRuntimeTest.cs和SZUIAtlasMakerRuntime.cs的代码示例,建议在游戏启动时运行以提高效率,并可以在游戏过程中将创建的Atlas保存到可写目录,以减少每次游戏启动时的创建过程。
摘要由CSDN通过智能技术生成

NGUI讨论群:333417608

NGUI版本:3.6.5


1、参见SZUIAtlasMakerRuntimeTest设置相应的值以上值需要提前设置好
2、没有检查是否atlas能够正确创建,自己可以改,加入返回值
3、代码都是在NGUI里面拷贝出来的,只是进行改动,没有新代码
4、适用与那种从网上下图片,之后还不想用UITexture的人,但是还是建议用UITexture如果drawcall不是问题的话
5、自己以后更新按我的方式改改就可以
6、动态创建速度较慢,建议在游戏启动的时候运行
7、游戏时可以将创建的atlas保存到可写目录,避免每次都新创建

SZUIAtlasMakerRuntimeTest.cs

using UnityEngine;
using System.Collections;

public class SZUIAtlasMakerRuntimeTest : MonoBehaviour {

	public Texture2D[] texs;
	public UISprite sprite;
	private UIAtlas atlas;

	void Start () {

		SZUIAtlasMakerRuntime.atlasTrimming = true;
		SZUIAtlasMakerRuntime.atlasPMA = atlas != null ? atlas.premultipliedAlpha : false;
		SZUIAtlasMakerRuntime.unityPacking = false;
		SZUIAtlasMakerRuntime.atlasPadding = 1;
		SZUIAtlasMakerRuntime.allow4096 = true;
		SZUIAtlasMakerRuntime.UITexturePacker.forceSquareAtlas = true;

		if (atlas == null)
		{
			atlas = this.gameObject.AddComponent<UIAtlas>();
		}
		string lastName = string.Empty;
		foreach (var tex in texs)
		{
			SZUIAtlasMakerRuntime.AddOrUpdate(atlas, tex);
			lastName = tex.name;
		}
		sprite.atlas = atlas;
		sprite.spriteName = lastName;
	}

}


SZUIAtlasMakerRuntime.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SZUIAtlasMakerRuntime {

	public static bool atlasTrimming = true;
	public static bool atlasPMA = false;
	public static bool unityPacking = false;
	public static int atlasPadding = 1;
	public static bool allow4096 = true;

	public 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;
	}

	/// <summary>
	/// Used to sort the sprites by pixels used
	/// </summary>
	
	static int Compare (SpriteEntry a, SpriteEntry b)
	{
		// A is null b is not b is greater so put it at the front of the list
		if (a == null && b != null) return 1;
		
		// A is not null b is null a is greater so put it at the front of the list
		if (a != null && b == null) return -1;
		
		// Get the total pixels used for each sprite
		int aPixels = a.width * a.height;
		int bPixels = b.width * b.height;
		
		if (aPixels > bPixels) return -1;
		else if (aPixels < bPixels) return 1;
		return 0;
	}

	/// <summary>
	/// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
	/// </summary>
	
	static bool PackTextures (Texture2D tex, List<SpriteEntry> sprites)
	{
		Texture2D[] textures = new Texture2D[sprites.Count];
		Rect[] rects;
		
		#if UNITY_3_5 || UNITY_4_0
		int maxSize = 4096;
		#else
		int maxSize = SystemInfo.maxTextureSize;
		#endif
		
		#if UNITY_ANDROID || UNITY_IPHONE
		maxSize = Mathf.Min(maxSize, allow4096 ? 4096 : 2048);
		#endif
		if (unityPacking)
		{
			for (int i = 0; i < sprites.Count; ++i) textures[i] = sprites[i].tex;
			rects = tex.PackTextures(textures, atlasPadding, maxSize);
		}
		else
		{
			sprites.Sort(Compare);
			for (int i = 0; i < sprites.Count; ++i) textures[i] = sprites[i].tex;
			rects = UITexturePacker.PackTextures(tex, textures, 4, 4, atlasPadding, maxSize);
		}
		
		for (int i = 0; i < sprites.Count; ++i)
		{
			Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);
			
			// Make sure that we don't shrink the textures
			if (Mathf.RoundToInt(rect.width) != textures[i].width) return false;
			
			SpriteEntry se = sprites[i];
			se.x = Mathf.RoundToInt(rect.x);
			se.y = Mathf.RoundToInt(rect.y);
			se.width = Mathf.RoundToInt(rect.width);
			se.height = Mathf.RoundToInt(rect.height);
		}
		return true;
	}

	static public void AddOrUpdate (UIAtlas atlas, Texture2D tex)
	{
		if (atlas != null && tex != null)
		{
			List<Texture> textures = new List<Texture>();
			textures.Add(tex);
			List<SpriteEntry> sprites = CreateSprites(textures);
			ExtractSprites(atlas, sprites);
			UpdateAtlas(atlas, sprites);
		}
	}
	
	/// <summary>
	/// Update the sprite atlas, keeping only the sprites that are on the specified list.
	/// </summary>
	
	static public void UpdateAtlas (UIAtlas atlas, List<SpriteEntry> sprites)
	{
		if (sprites.Count > 0)
		{
			// Combine all sprites into a single texture and save it
			if (UpdateTexture(atlas, sprites))
			{
				// Replace the sprites within the atlas
				ReplaceSprites(atlas, sprites);
			}
			
			// Release the temporary textures
			ReleaseSprites(sprites);
			return;
		}
		else
		{
			atlas.spriteList.Clear();
			NGUITools.Destroy(atlas.spriteMaterial.mainTexture);
			atlas.spriteMaterial.mainTexture = null;
		}
		
		atlas.MarkAsChanged();
	}

	/// <summary>
	/// Add a new sprite to the atlas, given the texture it's coming from and the packed rect within the atlas.
	/// </summary>
	
	static public UISpriteData AddSprite (List<UISpriteData> sprites, SpriteEntry se)
	{
		// See if this sprite already exists
		foreach (UISpriteData sp in sprites)
		{
			if (sp.name == se.name)
			{
				sp.CopyFrom(se);
				return sp;
			}
		}
		
		UISpriteData sprite = new UISpriteData();
		sprite.CopyFrom(se);
		sprites.Add(sprite);
		return sprite;
	}

	/// <summary>
	/// Create a list of sprites using the specified list of textures.
	/// </summary>
	/// 
	static public List<SpriteEntry> CreateSprites (List<Texture> textures)
	{
		List<SpriteEntry> list = new List<SpriteEntry>();
		
		foreach (Texture tex in textures)
		{
			Texture2D oldTex = tex as Texture2D;
			
			// If
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值