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