public bool AddTexture(Texture2D texture) { if (ExistTexture(texture)) { Debug.LogError("Contains repeating texture! " + texture.name); return(true); } bDirty = true; IntRect rect = mMaxRectsBinPack.Insert(texture.width, texture.height, mPackStrategy); if (rect == IntRect.zero) { return(false); } else { TextureAtlasElement element = new TextureAtlasElement { Offset = new IntVector2(rect.x, rect.y), Tex = texture, Scale = new IntVector2(rect.width / texture.width, rect.height / texture.height), Size = new IntVector2(texture.width, texture.height) }; ElementList.Add(element); return(true); } }
public void RemoveElementAt(int index) { if (index >= 0 && index < ElementList.Count) { TextureAtlasElement element = ElementList[index]; ElementList.RemoveAt(index); } else { Debug.LogError("Invalid index." + index); } }
private void WriteTexture() { Texture2D atlas = new Texture2D(Width, Height, TextureFormat.RGBA32, false); Color[] defaultColors = atlas.GetPixels(); //设置默认的颜色为黑色 Color defaultColor = new Color(0, 0, 0, 0); for (int i = 0; i < defaultColors.Length; ++i) { defaultColors[i] = defaultColor; } //把每张图片的像素写入atlas中. for (int i = 0; i < ElementList.Count; ++i) { TextureAtlasElement element = ElementList[i]; if (null != element && null != element.Tex) { Color[] colors = element.Tex.GetPixels(); int offsetX = (int)element.Offset.x; int offsetY = (int)element.Offset.y; for (int column = 0; column < element.Tex.width; ++column) { for (int row = 0; row < element.Tex.height; ++row) { int atlasColorIndex = (column + offsetX) + (row + offsetY) * atlas.width; int texColorIndex = column + row * element.Tex.width; defaultColors[atlasColorIndex] = colors[texColorIndex]; } } } } atlas.SetPixels(defaultColors); atlas.Apply(); Atlas = atlas; File.WriteAllBytes(AtlasPath, atlas.EncodeToPNG()); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); }
/// <summary> ///用Atlas替换掉Mesh使用的Material的小图 /// </summary> /// <param name="meshDataList"></param> public static void ReplaceTextureUseAtlas(List <MeshData> meshDataList) { List <TextureAtlas> atlasAssetList = new List <TextureAtlas>(); string[] assetFileArray = Directory.GetFiles(AtlasConfig.AssetDir, "*.asset", SearchOption.AllDirectories); for (int i = 0; i < assetFileArray.Length; ++i) { TextureAtlas textureAtlasAsset = AssetDatabase.LoadAssetAtPath <TextureAtlas>(assetFileArray[i]); if (null != textureAtlasAsset) { atlasAssetList.Add(textureAtlasAsset); } } for (int i = 0; i < meshDataList.Count; ++i) { MeshData meshData = meshDataList[i]; if (null != meshData) { Texture2D texture = meshData.material.mainTexture as Texture2D; for (int j = 0; j < atlasAssetList.Count; ++j) { TextureAtlas textureAtlas = atlasAssetList[j]; if (null != textureAtlas) { TextureAtlasElement element = textureAtlas.GetElement(texture); if (null != element) { meshData.texData = new TexData() { Atlas = textureAtlas, Element = element }; break; } } } if (null == meshData.texData) { Debug.LogError("Texture not combine to atlas. " + texture.name); } } } }
public override void OnInspectorGUI() { GUILayout.BeginVertical(); TextureAtlas textureAtlas = (TextureAtlas)target; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Atlas", GUILayout.Width(40)); EditorGUILayout.ObjectField(textureAtlas.Atlas, typeof(Texture2D), false, GUILayout.Width(150)); if (GUILayout.Button("Transform Visible", GUILayout.Width(120))) { bShowElementTransform = !bShowElementTransform; } EditorGUILayout.EndHorizontal(); GUILayout.Space(10); using (EditorGUILayout.VerticalScope scope = new EditorGUILayout.VerticalScope(GUILayout.Width(EditorGUIUtility.currentViewWidth - 5))) { for (int i = 0; i < textureAtlas.ElementList.Count; ++i) { GUILayout.Space(10); TextureAtlasElement element = textureAtlas.ElementList[i]; element.Tex = EditorGUILayout.ObjectField(element.Tex, typeof(Texture2D), false, GUILayout.Width(180)) as Texture2D; if (bShowElementTransform) { Vector2 offset = new Vector2(element.Offset.x, element.Offset.y); EditorGUILayout.Vector2Field("Offset", offset); Vector2 scale = new Vector2(element.Scale.x, element.Scale.y); EditorGUILayout.Vector2Field("Scale", scale); } } } GUILayout.EndVertical(); GUILayout.Space(10); base.OnInspectorGUI(); }
/// <summary> /// 在TextureAtlas从Asset实例化出来时,MaxRectsBinPack里面的数据是空的,这时把ElementList中的数据反排布到MaxRectsBinPack中 /// </summary> public void Layout() { mMaxRectsBinPack = new MaxRectsBinPack(Width, Height, AllowFlip); for (int i = ElementList.Count - 1; i >= 0; --i) { TextureAtlasElement element = ElementList[i]; if (null != element && null != element.Tex) { mMaxRectsBinPack.Layout((int)element.Offset.x, (int)element.Offset.y, element.Size.x, element.Size.y); } else { ElementList.RemoveAt(i); } } bDirty = true; }
public TextureAtlasElement GetElement(Texture2D texture) { for (int i = 0; i < ElementList.Count; ++i) { TextureAtlasElement element = ElementList[i]; if (null != element) { //防止出现同名但是图片对象不相同的情况(图片Unity格式不同,图片的TextureImporter的属性不同),造成资源冗余 if (element.Tex.name == texture.name && element.Tex != texture) { Debug.LogError("There are texture with the same name. " + element.Tex.name); } if (element.Tex == texture) { return(element); } } } return(null); }
/// <summary> /// 合并贴图 /// </summary> /// <param name="textureList"></param> /// <param name="atlasName"></param> /// <param name="isTransparent"></param> /// <param name="atlasWidth"></param> /// <param name="atlasHeight"></param> /// <returns></returns> private static List <TextureAtlas> PackAtlas(List <Texture2D> textureList, string atlasName, bool isTransparent, int atlasWidth, int atlasHeight) { int atlasIndex = 0; int textureCount = textureList.Count; textureList.Sort((a, b) => { return(a.width * a.height - b.width * b.height); }); List <TextureAtlas> atlasList = new List <TextureAtlas>(); string fileName = atlasName + "_" + atlasIndex; string assetPath = TextureAtlas.GetAssetPath(isTransparent, fileName); while (File.Exists(assetPath)) { TextureAtlas atlas = AssetDatabase.LoadAssetAtPath <TextureAtlas>(assetPath); if (null != atlas) { atlas.Layout(); atlasList.Add(atlas); } atlasIndex++; fileName = atlasName + "_" + atlasIndex; assetPath = TextureAtlas.GetAssetPath(isTransparent, fileName); } List <Texture2D> newlyTextures = new List <Texture2D>(); //找出新增的图片 for (int i = 0; i < textureList.Count; ++i) { bool found = false; for (int j = 0; j < atlasList.Count; ++j) { TextureAtlas atlas = atlasList[j]; if (null != atlas) { TextureAtlasElement element = atlas.GetElement(textureList[i]); if (null != element) { found = true; break; } } } if (!found) { newlyTextures.Add(textureList[i]); } } //Asset中删除图片已经删除的记录 for (int i = 0; i < atlasList.Count; ++i) { TextureAtlas atlas = atlasList[i]; for (int j = atlas.ElementList.Count - 1; j >= 0; --j) { Texture2D elementTex = atlas.ElementList[j].Tex; bool found = false; for (int m = 0; m < textureList.Count; ++m) { if (elementTex == textureList[m]) { found = true; break; } } if (!found) { atlas.RemoveElementAt(j); } } } //排列新增的图片 for (int i = 0; i < newlyTextures.Count; ++i) { Texture2D newlyTexture = newlyTextures[i]; if (null != newlyTexture) { bool added = false; for (int j = 0; j < atlasList.Count; ++j) { if (atlasList[j].AddTexture(newlyTexture)) { added = true; break; } } if (!added) { fileName = atlasName + "_" + atlasList.Count; assetPath = TextureAtlas.GetAssetPath(isTransparent, fileName); TextureAtlas atlas = ScriptableObject.CreateInstance <TextureAtlas>(); if (null != atlas) { atlas.Init(atlasWidth, atlasHeight, false, isTransparent, fileName); atlas.AddTexture(newlyTexture); atlasList.Add(atlas); } else { Debug.Log("Create atlas instance failed."); } } } } for (int i = 0; i < atlasList.Count; ++i) { EditorUtility.DisplayProgressBar("", "Pack atlas ", (i + 1) / atlasList.Count); atlasList[i].Pack(); } EditorUtility.ClearProgressBar(); return(atlasList); }