예제 #1
0
파일: UIAtlasMaker.cs 프로젝트: Kaiymu/RyS
    /// <summary>
    /// Add a new sprite to the atlas, given the texture it's coming from and the packed rect within the atlas.
    /// </summary>
    static UIAtlas.Sprite AddSprite(List<UIAtlas.Sprite> sprites, SpriteEntry se)
    {
        UIAtlas.Sprite sprite = null;

        // See if this sprite already exists
        foreach (UIAtlas.Sprite sp in sprites)
        {
            Debug.Log(se.tex.name + " " + sp.name);
            if (sp.name == se.tex.name)
            {
                sprite = sp;
                break;
            }
        }

        if (sprite != null)
        {
            float x0 = sprite.inner.xMin - sprite.outer.xMin;
            float y0 = sprite.inner.yMin - sprite.outer.yMin;
            float x1 = sprite.outer.xMax - sprite.inner.xMax;
            float y1 = sprite.outer.yMax - sprite.inner.yMax;

            sprite.outer = se.rect;
            sprite.inner = se.rect;

            sprite.inner.xMin = Mathf.Max(sprite.inner.xMin + x0, sprite.outer.xMin);
            sprite.inner.yMin = Mathf.Max(sprite.inner.yMin + y0, sprite.outer.yMin);
            sprite.inner.xMax = Mathf.Min(sprite.inner.xMax - x1, sprite.outer.xMax);
            sprite.inner.yMax = Mathf.Min(sprite.inner.yMax - y1, sprite.outer.yMax);
        }
        else
        {
            sprite = new UIAtlas.Sprite();
            sprite.name = se.tex.name;
            sprite.outer = se.rect;
            sprite.inner = se.rect;
            sprites.Add(sprite);
        }

        float width  = Mathf.Max(1f, sprite.outer.width);
        float height = Mathf.Max(1f, sprite.outer.height);

        // Sprite's padding values are relative to width and height
        sprite.paddingLeft	 = se.minX / width;
        sprite.paddingRight  = se.maxX / width;
        sprite.paddingTop	 = se.maxY / height;
        sprite.paddingBottom = se.minY / height;
        return sprite;
    }
예제 #2
0
    /// <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;
    }
예제 #3
0
    /// <summary>
    /// Add a new sprite to the atlas, given the texture it's coming from and the packed rect within the atlas.
    /// </summary>
    static 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;
    }
예제 #4
0
    /// <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 = NGUIEditorTools.ImportTexture(tex, true, false, true);
            if (oldTex == null)
            {
                oldTex = tex as Texture2D;
            }
            if (oldTex == null)
            {
                continue;
            }

            // If we aren't doing trimming, just use the texture as-is
            if (!NGUISettings.atlasTrimming && !NGUISettings.atlasPMA)
            {
                SpriteEntry sprite = new SpriteEntry();
                sprite.SetRect(0, 0, oldTex.width, oldTex.height);
                sprite.tex              = oldTex;
                sprite.name             = oldTex.name;
                sprite.temporaryTexture = false;
                list.Add(sprite);
                continue;
            }

            // If we want to trim transparent pixels, there is more work to be done
            Color32[] pixels = oldTex.GetPixels32();

            int xmin      = oldTex.width;
            int xmax      = 0;
            int ymin      = oldTex.height;
            int ymax      = 0;
            int oldWidth  = oldTex.width;
            int oldHeight = oldTex.height;

            // Find solid pixels
            if (NGUISettings.atlasTrimming)
            {
                for (int y = 0, yw = oldHeight; y < yw; ++y)
                {
                    for (int x = 0, xw = oldWidth; x < xw; ++x)
                    {
                        Color32 c = pixels[y * xw + x];

                        if (c.a != 0)
                        {
                            if (y < ymin)
                            {
                                ymin = y;
                            }
                            if (y > ymax)
                            {
                                ymax = y;
                            }
                            if (x < xmin)
                            {
                                xmin = x;
                            }
                            if (x > xmax)
                            {
                                xmax = x;
                            }
                        }
                    }
                }
            }
            else
            {
                xmin = 0;
                xmax = oldWidth - 1;
                ymin = 0;
                ymax = oldHeight - 1;
            }

            int newWidth  = (xmax - xmin) + 1;
            int newHeight = (ymax - ymin) + 1;

            if (newWidth > 0 && newHeight > 0)
            {
                SpriteEntry sprite = new SpriteEntry();
                sprite.x      = 0;
                sprite.y      = 0;
                sprite.width  = oldTex.width;
                sprite.height = oldTex.height;

                // If the dimensions match, then nothing was actually trimmed
                if (!NGUISettings.atlasPMA && (newWidth == oldWidth && newHeight == oldHeight))
                {
                    sprite.tex              = oldTex;
                    sprite.name             = oldTex.name;
                    sprite.temporaryTexture = false;
                }
                else
                {
                    // Copy the non-trimmed texture data into a temporary buffer
                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = y * newWidth + x;
                            int oldIndex = (ymin + y) * oldWidth + (xmin + x);
                            if (NGUISettings.atlasPMA)
                            {
                                newPixels[newIndex] = NGUITools.ApplyPMA(pixels[oldIndex]);
                            }
                            else
                            {
                                newPixels[newIndex] = pixels[oldIndex];
                            }
                        }
                    }

                    // Create a new texture
                    sprite.name = oldTex.name;
                    sprite.SetTexture(newPixels, newWidth, newHeight);

                    // Remember the padding offset
                    sprite.SetPadding(xmin, ymin, oldWidth - newWidth - xmin, oldHeight - newHeight - ymin);
                }
                list.Add(sprite);
            }
        }
        return(list);
    }
예제 #5
0
    /// <summary>
    /// Draw the UI for this tool.
    /// </summary>

    void OnGUI()
    {
        bool create  = false;
        bool update  = false;
        bool replace = false;

        string prefabPath = "";
        string matPath    = "";

        // If we have an atlas to work with, see if we can figure out the path for it and its material
        if (NGUISettings.atlas != null && NGUISettings.atlas.name == NGUISettings.atlasName)
        {
            prefabPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.gameObject.GetInstanceID());
            if (NGUISettings.atlas.spriteMaterial != null)
            {
                matPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.spriteMaterial.GetInstanceID());
            }
        }

        // Assume default values if needed
        if (string.IsNullOrEmpty(NGUISettings.atlasName))
        {
            NGUISettings.atlasName = "New Atlas";
        }
        if (string.IsNullOrEmpty(prefabPath))
        {
            prefabPath = NGUIEditorTools.GetSelectionFolder() + NGUISettings.atlasName + ".prefab";
        }
        if (string.IsNullOrEmpty(matPath))
        {
            matPath = NGUIEditorTools.GetSelectionFolder() + NGUISettings.atlasName + ".mat";
        }

        // Try to load the prefab
        GameObject go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;

        if (NGUISettings.atlas == null && go != null)
        {
            NGUISettings.atlas = go.GetComponent <UIAtlas>();
        }

        NGUIEditorTools.SetLabelWidth(80f);

        GUILayout.Space(6f);
        GUILayout.BeginHorizontal();

        if (go == null)
        {
            GUI.backgroundColor = Color.green;
            create = GUILayout.Button("Create", GUILayout.Width(76f));
        }
        else
        {
            GUI.backgroundColor = Color.red;
            create = GUILayout.Button("Replace", GUILayout.Width(76f));
        }

        GUI.backgroundColor    = Color.white;
        NGUISettings.atlasName = GUILayout.TextField(NGUISettings.atlasName);
        GUILayout.EndHorizontal();

        if (create)
        {
            // If the prefab already exists, confirm that we want to overwrite it
            if (go == null || EditorUtility.DisplayDialog("Are you sure?", "Are you sure you want to replace the contents of the " +
                                                          NGUISettings.atlasName + " atlas with the textures currently selected in the Project View? All other sprites will be deleted.", "Yes", "No"))
            {
                replace = true;

                // Try to load the material
                Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

                // If the material doesn't exist, create it
                if (mat == null)
                {
                    Shader shader = Shader.Find(NGUISettings.atlasPMA ? "Unlit/Premultiplied Colored" : "Unlit/Transparent Colored");
                    mat = new Material(shader);

                    // Save the material
                    AssetDatabase.CreateAsset(mat, matPath);
                    AssetDatabase.Refresh();

                    // Load the material so it's usable
                    mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
                }

                if (NGUISettings.atlas == null || NGUISettings.atlas.name != NGUISettings.atlasName)
                {
                    // Create a new prefab for the atlas
                    Object prefab = (go != null) ? go : PrefabUtility.CreateEmptyPrefab(prefabPath);

                    // Create a new game object for the atlas
                    go = new GameObject(NGUISettings.atlasName);
                    go.AddComponent <UIAtlas>().spriteMaterial = mat;

                    // Update the prefab
                    PrefabUtility.ReplacePrefab(go, prefab);
                    DestroyImmediate(go);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();

                    // Select the atlas
                    go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                    NGUISettings.atlas = go.GetComponent <UIAtlas>();
                }
            }
        }

        ComponentSelector.Draw <UIAtlas>("Select", NGUISettings.atlas, OnSelectAtlas, true);

        List <Texture> textures = GetSelectedTextures();

        if (NGUISettings.atlas != null && NGUISettings.atlas.name == NGUISettings.atlasName)
        {
            Material mat = NGUISettings.atlas.spriteMaterial;
            Texture  tex = NGUISettings.atlas.texture;

            // Material information
            GUILayout.BeginHorizontal();
            {
                if (mat != null)
                {
                    if (GUILayout.Button("Material", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = mat;
                    }
                    GUILayout.Label(" " + mat.name);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Material", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();

            // Texture atlas information
            GUILayout.BeginHorizontal();
            {
                if (tex != null)
                {
                    if (GUILayout.Button("Texture", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = tex;
                    }
                    GUILayout.Label(" " + tex.width + "x" + tex.height);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Texture", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();
        }

        GUILayout.BeginHorizontal();
        NGUISettings.atlasPadding = Mathf.Clamp(EditorGUILayout.IntField("Padding", NGUISettings.atlasPadding, GUILayout.Width(100f)), 0, 8);
        GUILayout.Label((NGUISettings.atlasPadding == 1 ? "pixel" : "pixels") + " in-between of sprites");
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        NGUISettings.atlasTrimming = EditorGUILayout.Toggle("Trim Alpha", NGUISettings.atlasTrimming, GUILayout.Width(100f));
        GUILayout.Label("Remove empty space");
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        NGUISettings.atlasPMA = EditorGUILayout.Toggle("PMA Shader", NGUISettings.atlasPMA, GUILayout.Width(100f));
        GUILayout.Label("Pre-multiply color by alpha");
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        NGUISettings.unityPacking = EditorGUILayout.Toggle("Unity Packer", NGUISettings.unityPacking, GUILayout.Width(100f));
        GUILayout.Label("if off, use a custom packer");
        GUILayout.EndHorizontal();

        if (!NGUISettings.unityPacking)
        {
            GUILayout.BeginHorizontal();
            NGUISettings.forceSquareAtlas = EditorGUILayout.Toggle("Force Square", NGUISettings.forceSquareAtlas, GUILayout.Width(100f));
            GUILayout.Label("if on, forces a square atlas texture");
            GUILayout.EndHorizontal();
        }

#if UNITY_IPHONE || UNITY_ANDROID
        GUILayout.BeginHorizontal();
        NGUISettings.allow4096 = EditorGUILayout.Toggle("4096x4096", NGUISettings.allow4096, GUILayout.Width(100f));
        GUILayout.Label("if off, limit atlases to 2048x2048");
        GUILayout.EndHorizontal();
#endif
        if (NGUISettings.atlas != null && NGUISettings.atlas.name == NGUISettings.atlasName)
        {
            if (textures.Count > 0)
            {
                GUI.backgroundColor = Color.green;
                update = GUILayout.Button("Add/Update All");
                GUI.backgroundColor = Color.white;
            }
            else
            {
                EditorGUILayout.HelpBox("You can reveal more options by selecting one or more textures in the Project View window.", MessageType.Info);
            }
        }
        else
        {
            EditorGUILayout.HelpBox("You can create a new atlas by selecting one or more textures in the Project View window, then clicking \"Create\".", MessageType.Info);
        }

        string selection = null;
        Dictionary <string, int> spriteList = GetSpriteList(textures);

        if (spriteList.Count > 0)
        {
            NGUIEditorTools.DrawHeader("Sprites", true);
            {
                GUILayout.BeginHorizontal();
                GUILayout.Space(3f);
                GUILayout.BeginVertical();

                mScroll = GUILayout.BeginScrollView(mScroll);

                bool delete = false;
                int  index  = 0;
                foreach (KeyValuePair <string, int> iter in spriteList)
                {
                    ++index;

                    GUILayout.Space(-1f);
                    bool highlight = (UIAtlasInspector.instance != null) && (NGUISettings.selectedSprite == iter.Key);
                    GUI.backgroundColor = highlight ? Color.white : new Color(0.8f, 0.8f, 0.8f);
                    GUILayout.BeginHorizontal("AS TextArea", GUILayout.MinHeight(20f));
                    GUI.backgroundColor = Color.white;
                    GUILayout.Label(index.ToString(), GUILayout.Width(24f));

                    if (GUILayout.Button(iter.Key, "OL TextField", GUILayout.Height(20f)))
                    {
                        selection = iter.Key;
                    }

                    if (iter.Value == 2)
                    {
                        GUI.color = Color.green;
                        GUILayout.Label("Add", GUILayout.Width(27f));
                        GUI.color = Color.white;
                    }
                    else if (iter.Value == 1)
                    {
                        GUI.color = Color.cyan;
                        GUILayout.Label("Update", GUILayout.Width(45f));
                        GUI.color = Color.white;
                    }
                    else
                    {
                        if (mDelNames.Contains(iter.Key))
                        {
                            GUI.backgroundColor = Color.red;

                            if (GUILayout.Button("Delete", GUILayout.Width(60f)))
                            {
                                delete = true;
                            }
                            GUI.backgroundColor = Color.green;
                            if (GUILayout.Button("X", GUILayout.Width(22f)))
                            {
                                mDelNames.Remove(iter.Key);
                                delete = false;
                            }
                            GUI.backgroundColor = Color.white;
                        }
                        else
                        {
                            // If we have not yet selected a sprite for deletion, show a small "X" button
                            if (GUILayout.Button("X", GUILayout.Width(22f)))
                            {
                                mDelNames.Add(iter.Key);
                            }
                        }
                    }
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndScrollView();
                GUILayout.EndVertical();
                GUILayout.Space(3f);
                GUILayout.EndHorizontal();

                // If this sprite was marked for deletion, remove it from the atlas
                if (delete)
                {
                    List <SpriteEntry> sprites = new List <SpriteEntry>();
                    ExtractSprites(NGUISettings.atlas, sprites);

                    for (int i = sprites.Count; i > 0;)
                    {
                        SpriteEntry ent = sprites[--i];
                        if (mDelNames.Contains(ent.name))
                        {
                            sprites.RemoveAt(i);
                        }
                    }
                    UpdateAtlas(NGUISettings.atlas, sprites);
                    mDelNames.Clear();
                }
                else if (update)
                {
                    UpdateAtlas(textures, true);
                }
                else if (replace)
                {
                    UpdateAtlas(textures, false);
                }

                if (NGUISettings.atlas != null && !string.IsNullOrEmpty(selection))
                {
                    NGUISettings.selectedSprite = selection;
                    Selection.activeGameObject  = NGUISettings.atlas.gameObject;

                    if (UIAtlasInspector.instance != null)
                    {
                        UIAtlasInspector.instance.Repaint();
                    }
                }
                else if (update || replace)
                {
                    NGUIEditorTools.UpgradeTexturesToSprites(NGUISettings.atlas);
                }
            }
        }

        // Uncomment this line if you want to be able to force-sort the atlas
        //if (NGUISettings.atlas != null && GUILayout.Button("Sort Alphabetically")) NGUISettings.atlas.SortAlphabetically();
    }
예제 #6
0
    /// <summary>
    /// Extract sprites from the atlas, adding them to the list.
    /// </summary>

    static void ExtractSprites(UIAtlas atlas, List <SpriteEntry> finalSprites)
    {
        // Make the atlas texture readable
        Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false, !atlas.premultipliedAlpha);

        if (atlasTex != null)
        {
            Color32[]           oldPixels       = null;
            int                 oldWidth        = atlasTex.width;
            int                 oldHeight       = atlasTex.height;
            List <UISpriteData> existingSprites = atlas.spriteList;

            foreach (UISpriteData es in existingSprites)
            {
                bool found = false;

                foreach (SpriteEntry fs in finalSprites)
                {
                    if (es.name == fs.name)
                    {
                        fs.CopyBorderFrom(es);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    // Read the atlas
                    if (oldPixels == null)
                    {
                        oldPixels = atlasTex.GetPixels32();
                    }

                    int xmin      = Mathf.Clamp(es.x, 0, oldWidth);
                    int ymin      = Mathf.Clamp(es.y, 0, oldHeight);
                    int newWidth  = Mathf.Clamp(es.width, 0, oldWidth);
                    int newHeight = Mathf.Clamp(es.height, 0, oldHeight);
                    if (newWidth == 0 || newHeight == 0)
                    {
                        continue;
                    }

                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = (newHeight - 1 - y) * newWidth + x;
                            int oldIndex = (oldHeight - 1 - (ymin + y)) * oldWidth + (xmin + x);
                            newPixels[newIndex] = oldPixels[oldIndex];
                        }
                    }

                    // Create a new sprite
                    SpriteEntry sprite = new SpriteEntry();
                    sprite.CopyFrom(es);
                    sprite.SetRect(0, 0, newWidth, newHeight);
                    sprite.temporaryTexture = true;
                    sprite.tex = new Texture2D(newWidth, newHeight);
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();
                    finalSprites.Add(sprite);
                }
            }
        }

        // The atlas no longer needs to be readable
        NGUIEditorTools.ImportTexture(atlas.texture, false, false, !atlas.premultipliedAlpha);
    }
예제 #7
0
	/// <summary>
	/// Create a list of sprites using the specified list of textures.
	/// </summary>

	static List<SpriteEntry> CreateSprites (List<Texture> textures)
	{
		List<SpriteEntry> list = new List<SpriteEntry>();

		foreach (Texture tex in textures)
		{
			Texture2D oldTex = NGUIEditorTools.ImportTexture(tex, true, false);
			if (oldTex == null) continue;

			// If we aren't doing trimming, just use the texture as-is
			if (!NGUISettings.atlasTrimming)
			{
				SpriteEntry sprite = new SpriteEntry();
				sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);
				sprite.tex = oldTex;
				sprite.temporaryTexture = false;
				list.Add(sprite);
				continue;
			}

			// If we want to trim transparent pixels, there is more work to be done
			Color32[] pixels = oldTex.GetPixels32();

			int xmin = oldTex.width;
			int xmax = 0;
			int ymin = oldTex.height;
			int ymax = 0;
			int oldWidth = oldTex.width;
			int oldHeight = oldTex.height;

			// Find solid pixels
			for (int y = 0, yw = oldHeight; y < yw; ++y)
			{
				for (int x = 0, xw = oldWidth; x < xw; ++x)
				{
					Color32 c = pixels[y * xw + x];

					if (c.a != 0)
					{
						if (y < ymin) ymin = y;
						if (y > ymax) ymax = y;
						if (x < xmin) xmin = x;
						if (x > xmax) xmax = x;
					}
				}
			}

			int newWidth  = (xmax - xmin) + 1;
			int newHeight = (ymax - ymin) + 1;

			// If the sprite is empty, don't do anything with it
			if (newWidth > 0 && newHeight > 0)
			{
				SpriteEntry sprite = new SpriteEntry();
				sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);

				// If the dimensions match, then nothing was actually trimmed
				if (newWidth == oldWidth && newHeight == oldHeight)
				{
					sprite.tex = oldTex;
					sprite.temporaryTexture = false;
				}
				else
				{
					// Copy the non-trimmed texture data into a temporary buffer
					Color32[] newPixels = new Color32[newWidth * newHeight];

					for (int y = 0; y < newHeight; ++y)
					{
						for (int x = 0; x < newWidth; ++x)
						{
							int newIndex = y * newWidth + x;
							int oldIndex = (ymin + y) * oldWidth + (xmin + x);
							newPixels[newIndex] = pixels[oldIndex];
						}
					}

					// Create a new texture
					sprite.temporaryTexture = true;
					sprite.tex = new Texture2D(newWidth, newHeight);
					sprite.tex.name = oldTex.name;
					sprite.tex.SetPixels32(newPixels);
					sprite.tex.Apply();

					// Remember the padding offset
					sprite.minX = xmin;
					sprite.maxX = oldWidth - newWidth - xmin;
					sprite.minY = ymin;
					sprite.maxY = oldHeight - newHeight - ymin;
				}
				list.Add(sprite);
			}
		}
		return list;
	}
예제 #8
0
	/// <summary>
	/// Extract the specified sprite from the atlas texture.
	/// </summary>

	static SpriteEntry ExtractSprite (UISpriteData es, Color32[] oldPixels, int oldWidth, int oldHeight)
	{
		int xmin = Mathf.Clamp(es.x, 0, oldWidth);
		int ymin = Mathf.Clamp(es.y, 0, oldHeight);
		int xmax = Mathf.Min(xmin + es.width, oldWidth - 1);
		int ymax = Mathf.Min(ymin + es.height, oldHeight - 1);
		int newWidth = Mathf.Clamp(es.width, 0, oldWidth);
		int newHeight = Mathf.Clamp(es.height, 0, oldHeight);

		if (newWidth == 0 || newHeight == 0) return null;

		Color32[] newPixels = new Color32[newWidth * newHeight];

		for (int y = 0; y < newHeight; ++y)
		{
			int cy = ymin + y;
			if (cy > ymax) cy = ymax;

			for (int x = 0; x < newWidth; ++x)
			{
				int cx = xmin + x;
				if (cx > xmax) cx = xmax;

				int newIndex = (newHeight - 1 - y) * newWidth + x;
				int oldIndex = (oldHeight - 1 - cy) * oldWidth + cx;

				newPixels[newIndex] = oldPixels[oldIndex];
			}
		}

		// Create a new sprite
		SpriteEntry sprite = new SpriteEntry();
		sprite.CopyFrom(es);
		sprite.SetRect(0, 0, newWidth, newHeight);
		sprite.temporaryTexture = true;
		sprite.tex = new Texture2D(newWidth, newHeight);
		sprite.tex.SetPixels32(newPixels);
		sprite.tex.Apply();
		return sprite;
	}
예제 #9
0
    /// <summary>
    /// Create a list of sprites using the specified list of textures.
    /// </summary>

    static List <SpriteEntry> CreateSprites(List <Texture> textures)
    {
        List <SpriteEntry> list = new List <SpriteEntry>();

        foreach (Texture tex in textures)
        {
            Texture2D oldTex = NGUIEditorTools.ImportTexture(tex, true, false);
            if (oldTex == null)
            {
                continue;
            }

            Color32[] pixels = oldTex.GetPixels32();

            int xmin      = oldTex.width;
            int xmax      = 0;
            int ymin      = oldTex.height;
            int ymax      = 0;
            int oldWidth  = oldTex.width;
            int oldHeight = oldTex.height;

            for (int y = 0, yw = oldHeight; y < yw; ++y)
            {
                for (int x = 0, xw = oldWidth; x < xw; ++x)
                {
                    Color32 c = pixels[y * xw + x];

                    if (c.a != 0)
                    {
                        if (y < ymin)
                        {
                            ymin = y;
                        }
                        if (y > ymax)
                        {
                            ymax = y;
                        }
                        if (x < xmin)
                        {
                            xmin = x;
                        }
                        if (x > xmax)
                        {
                            xmax = x;
                        }
                    }
                }
            }

            int newWidth  = (xmax - xmin) + 1;
            int newHeight = (ymax - ymin) + 1;

            if (newWidth > 0 && newHeight > 0)
            {
                SpriteEntry sprite = new SpriteEntry();
                sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);

                if (newWidth == oldWidth && newHeight == oldHeight)
                {
                    sprite.tex = oldTex;
                    sprite.temporaryTexture = false;
                }
                else
                {
                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = y * newWidth + x;
                            int oldIndex = (ymin + y) * oldWidth + (xmin + x);
                            newPixels[newIndex] = pixels[oldIndex];
                        }
                    }

                    // Create a new texture
                    sprite.temporaryTexture = true;
                    sprite.tex      = new Texture2D(newWidth, newHeight);
                    sprite.tex.name = oldTex.name;
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();

                    // Remember the padding offset
                    sprite.minX = xmin;
                    sprite.maxX = oldWidth - newWidth - xmin;
                    sprite.minY = ymin;
                    sprite.maxY = oldHeight - newHeight - ymin;
                }
                list.Add(sprite);
            }
        }
        return(list);
    }
예제 #10
0
    static List <SpriteEntry> CreateSprites(List <Texture> textures)
    {
        List <SpriteEntry> list = new List <SpriteEntry>();

        foreach (Texture tex in textures)
        {
            Texture2D oldTex = tex as Texture2D;
            if (oldTex == null)
            {
                continue;
            }
            // If we want to trim transparent pixels, there is more work to be done
            Color32[] pixels = oldTex.GetPixels32();

            int xmin      = oldTex.width;
            int xmax      = 0;
            int ymin      = oldTex.height;
            int ymax      = 0;
            int oldWidth  = oldTex.width;
            int oldHeight = oldTex.height;

            // Find solid pixels
            for (int y = 0, yw = oldHeight; y < yw; ++y)
            {
                for (int x = 0, xw = oldWidth; x < xw; ++x)
                {
                    Color32 c = pixels[y * xw + x];

                    if (c.a != 0)
                    {
                        if (y < ymin)
                        {
                            ymin = y;
                        }
                        if (y > ymax)
                        {
                            ymax = y;
                        }
                        if (x < xmin)
                        {
                            xmin = x;
                        }
                        if (x > xmax)
                        {
                            xmax = x;
                        }
                    }
                }
            }

            int newWidth  = (xmax - xmin) + 1;
            int newHeight = (ymax - ymin) + 1;

            // If the sprite is empty, don't do anything with it
            if (newWidth > 0 && newHeight > 0)
            {
                SpriteEntry sprite = new SpriteEntry();
                sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);

                // If the dimensions match, then nothing was actually trimmed
                if (newWidth == oldWidth && newHeight == oldHeight)
                {
                    sprite.tex = oldTex;
                    sprite.temporaryTexture = false;
                }
                else
                {
                    // Copy the non-trimmed texture data into a temporary buffer
                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = y * newWidth + x;
                            int oldIndex = (ymin + y) * oldWidth + (xmin + x);
                            newPixels[newIndex] = pixels[oldIndex];
                        }
                    }

                    // Create a new texture
                    sprite.temporaryTexture = true;
                    sprite.tex      = new Texture2D(newWidth, newHeight);
                    sprite.tex.name = oldTex.name;
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();

                    // Remember the padding offset
                    sprite.minX = xmin;
                    sprite.maxX = oldWidth - newWidth - xmin;
                    sprite.minY = ymin;
                    sprite.maxY = oldHeight - newHeight - ymin;
                }
                list.Add(sprite);
            }
        }
        return(list);
    }
예제 #11
0
    /// <summary>
    /// Extract sprites from the atlas, adding them to the list.
    /// </summary>
    static void ExtractSprites(UIAtlas atlas, List<SpriteEntry> sprites)
    {
        // Make the atlas texture readable
        Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false, !atlas.premultipliedAlpha);

        if (atlasTex != null)
        {
            Color32[] oldPixels = null;
            int oldWidth = atlasTex.width;
            int oldHeight = atlasTex.height;
            List<UISpriteData> list = atlas.spriteList;

            foreach (UISpriteData asp in list)
            {
                bool found = false;

                foreach (SpriteEntry se in sprites)
                {
                    if (asp.name == se.name)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    // Read the atlas
                    if (oldPixels == null) oldPixels = atlasTex.GetPixels32();

                    int xmin = Mathf.Clamp(asp.x, 0, oldWidth);
                    int ymin = Mathf.Clamp(asp.y, 0, oldHeight);
                    int newWidth = Mathf.Clamp(asp.width, 0, oldWidth);
                    int newHeight = Mathf.Clamp(asp.height, 0, oldHeight);
                    if (newWidth == 0 || newHeight == 0) continue;

                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = (newHeight - 1 - y) * newWidth + x;
                            int oldIndex = (oldHeight - 1 - (ymin + y)) * oldWidth + (xmin + x);
                            newPixels[newIndex] = oldPixels[oldIndex];
                        }
                    }

                    // Create a new sprite
                    SpriteEntry sprite = new SpriteEntry();
                    sprite.CopyFrom(asp);
                    sprite.SetRect(0, 0, newWidth, newHeight);
                    sprite.temporaryTexture = true;
                    sprite.tex = new Texture2D(newWidth, newHeight);
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();
                    sprites.Add(sprite);
                }
            }
        }

        // The atlas no longer needs to be readable
        NGUIEditorTools.ImportTexture(atlas.texture, false, false, !atlas.premultipliedAlpha);
    }
예제 #12
0
        private static void WriteSprite(BBData data, SpriteInfo si, StringsChunkBuilder strings, int[] texPagOffsets)
        {
            var se = new SpriteEntry
            {
                Name     = strings.GetOffset(si.Name),
                Size     = si.Size,
                Bounding = si.Bounding,
                BBoxMode = si.BBoxMode,
                Origin   = si.Origin,

                SeparateColMasks = si.SeparateColMasks ? DwordBool.True : DwordBool.False
            };

            var tmp = new BinBuffer();

            tmp.Write(se);
            data.Buffer.Write(tmp, 0, tmp.Size - 8, 0);

            if (si.Version >= 2)
            {
                var se2 = new SpriteEntry2();
                unsafe
                {
                    se2._pad2[0] = -1;
                    se2._pad2[1] = 1;
                    se2._pad2[2] = 0;
                }
                se2.funk = si.UnknownFloat;
                tmp      = new BinBuffer();
                tmp.Write(se2);
                data.Buffer.Write(tmp, 0, 0x14, 0x38);
            }

            if (si.TextureIndices == null)
            {
                data.Buffer.Write(0xFFFFFFFF);
            }
            else
            {
                data.Buffer.Write(si.TextureIndices.Length);
                foreach (var ti in si.TextureIndices)
                {
                    data.Buffer.Write(texPagOffsets[ti]);
                }

                if (si.CollisionMasks == null)
                {
                    data.Buffer.Write(0xFFFFFFFF);
                }
                else
                {
                    data.Buffer.Write((uint)si.CollisionMasks.Length);
                    foreach (var mask in si.CollisionMasks)
                    {
                        int w = mask.GetLength(0);
                        for (int y = 0; y < mask.GetLength(1); y++)
                        {
                            for (int x = 0; x < w; x += 8)
                            {
                                byte b = 0;
                                if (x < w && mask[x, y])
                                {
                                    b |= 0b00000001;
                                }
                                if (x + 1 < w && mask[x + 1, y])
                                {
                                    b |= 0b00000010;
                                }
                                if (x + 2 < w && mask[x + 2, y])
                                {
                                    b |= 0b00000100;
                                }
                                if (x + 3 < w && mask[x + 3, y])
                                {
                                    b |= 0b00001000;
                                }
                                if (x + 4 < w && mask[x + 4, y])
                                {
                                    b |= 0b00010000;
                                }
                                if (x + 5 < w && mask[x + 5, y])
                                {
                                    b |= 0b00100000;
                                }
                                if (x + 6 < w && mask[x + 6, y])
                                {
                                    b |= 0b01000000;
                                }
                                if (x + 7 < w && mask[x + 7, y])
                                {
                                    b |= 0b10000000;
                                }
                                data.Buffer.Write(b);
                            }
                        }
                    }
                }
            }
            Pad(data, 4, 0);
        }
예제 #13
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, NGUISettings.allow4096 ? 4096 : 2048);
#endif
        if (NGUISettings.unityPacking)
        {
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = tex.PackTextures(textures, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), 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, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), maxSize);
        }

        for (int i = 0; i < sprites.Count; ++i)
        {
            Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);

            // Apparently Unity can take the liberty of destroying temporary textures without any warning
            if (textures[i] == null)
            {
                return(false);
            }

            // 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);
        }

        if (NGUISettings.atlasExtendPadding > 0)
        {
            Color32[] colors    = tex.GetPixels32();
            int       texWidth  = tex.width;
            int       texHeight = tex.height;
            for (int i = 0; i < sprites.Count; ++i)
            {
                SpriteEntry se   = sprites[i];
                int         xMin = se.x;
                int         xMax = se.x + se.width - 1;
                // Y-axis is inverted
                int yMin = texHeight - se.y - se.height;
                int yMax = texHeight - se.y - 1;
                for (int x = xMin - NGUISettings.atlasExtendPadding; x <= xMax + NGUISettings.atlasExtendPadding; ++x)
                {
                    for (int y = yMin - NGUISettings.atlasExtendPadding; y <= yMax + NGUISettings.atlasExtendPadding; ++y)
                    {
                        if (x < 0 || x >= texWidth || y < 0 || y >= texHeight)
                        {
                            // Out of tex bounds
                            continue;
                        }
                        if (x >= xMin && x <= xMax && y >= yMin && y <= yMax)
                        {
                            // In sprite bounds
                            continue;
                        }
                        int baseX     = Mathf.Clamp(x, xMin, xMax);
                        int baseY     = Mathf.Clamp(y, yMin, yMax);
                        int index     = y * texWidth + x;
                        int baseIndex = baseY * texWidth + baseX;
                        colors[index] = colors[baseIndex];
                    }
                }
            }
            tex.SetPixels32(colors);
        }

        return(true);
    }
		static UIAtlas.Sprite AddSprite(ICollection<UIAtlas.Sprite> sprites, SpriteEntry se)
		{
			UIAtlas.Sprite sprite = sprites.FirstOrDefault(sp => sp.name == se.Tex.name);

			// See if this sprite already exists

			if (sprite != null)
			{
				float x0 = sprite.inner.xMin - sprite.outer.xMin;
				float y0 = sprite.inner.yMin - sprite.outer.yMin;
				float x1 = sprite.outer.xMax - sprite.inner.xMax;
				float y1 = sprite.outer.yMax - sprite.inner.yMax;

				sprite.outer = se.Rect;
				sprite.inner = se.Rect;

				sprite.inner.xMin = Mathf.Max(sprite.inner.xMin + x0, sprite.outer.xMin);
				sprite.inner.yMin = Mathf.Max(sprite.inner.yMin + y0, sprite.outer.yMin);
				sprite.inner.xMax = Mathf.Min(sprite.inner.xMax - x1, sprite.outer.xMax);
				sprite.inner.yMax = Mathf.Min(sprite.inner.yMax - y1, sprite.outer.yMax);
			}
			else
			{
				sprite = new UIAtlas.Sprite {name = se.Tex.name, outer = se.Rect, inner = se.Rect};
				sprites.Add(sprite);
			}

			float width = Mathf.Max(1f, sprite.outer.width);
			float height = Mathf.Max(1f, sprite.outer.height);

			// Sprite's padding values are relative to width and height
			sprite.paddingLeft = se.MinX / width;
			sprite.paddingRight = se.MaxX / width;
			sprite.paddingTop = se.MaxY / height;
			sprite.paddingBottom = se.MinY / height;
			return sprite;
		}
예제 #15
0
    /// <summary>
    /// Draw the UI for this tool.
    /// </summary>

    void OnGUI()
    {
        if (mLastAtlas != NGUISettings.atlas)
        {
            mLastAtlas = NGUISettings.atlas;
        }

        bool update  = false;
        bool replace = false;

        NGUIEditorTools.SetLabelWidth(84f);
        GUILayout.Space(3f);

        NGUIEditorTools.DrawHeader("Input", true);
        NGUIEditorTools.BeginContents(false);

        GUILayout.BeginHorizontal();
        {
            ComponentSelector.Draw <UIAtlas>("Atlas", NGUISettings.atlas, OnSelectAtlas, true, GUILayout.MinWidth(80f));

            EditorGUI.BeginDisabledGroup(NGUISettings.atlas == null);
            if (GUILayout.Button("New", GUILayout.Width(40f)))
            {
                NGUISettings.atlas = null;
            }
            EditorGUI.EndDisabledGroup();
        }
        GUILayout.EndHorizontal();

        List <Texture> textures = GetSelectedTextures();

        if (NGUISettings.atlas != null)
        {
            Material mat = NGUISettings.atlas.spriteMaterial;
            Texture  tex = NGUISettings.atlas.texture;

            // Material information
            GUILayout.BeginHorizontal();
            {
                if (mat != null)
                {
                    if (GUILayout.Button("Material", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = mat;
                    }
                    GUILayout.Label(" " + mat.name);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Material", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();

            // Texture atlas information
            GUILayout.BeginHorizontal();
            {
                if (tex != null)
                {
                    if (GUILayout.Button("Texture", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = tex;
                    }
                    GUILayout.Label(" " + tex.width + "x" + tex.height);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Texture", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();
        }

        GUILayout.BeginHorizontal();
        NGUISettings.atlasPadding = Mathf.Clamp(EditorGUILayout.IntField("Padding", NGUISettings.atlasPadding, GUILayout.Width(100f)), 0, 8);
        GUILayout.Label((NGUISettings.atlasPadding == 1 ? "pixel" : "pixels") + " between sprites");
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        NGUISettings.atlasTrimming = EditorGUILayout.Toggle("Trim Alpha", NGUISettings.atlasTrimming, GUILayout.Width(100f));
        GUILayout.Label("Remove empty space");
        GUILayout.EndHorizontal();

        bool fixedShader = false;

        if (NGUISettings.atlas != null)
        {
            Material mat = NGUISettings.atlas.spriteMaterial;

            if (mat != null)
            {
                Shader shader = mat.shader;

                if (shader != null)
                {
                    if (shader.name == "Unlit/Transparent Colored")
                    {
                        NGUISettings.atlasPMA = false;
                        fixedShader           = true;
                    }
                    else if (shader.name == "Unlit/Premultiplied Colored")
                    {
                        NGUISettings.atlasPMA = true;
                        fixedShader           = true;
                    }
                }
            }
        }

        if (!fixedShader)
        {
            GUILayout.BeginHorizontal();
            NGUISettings.atlasPMA = EditorGUILayout.Toggle("PMA Shader", NGUISettings.atlasPMA, GUILayout.Width(100f));
            GUILayout.Label("Pre-multiplied alpha", GUILayout.MinWidth(70f));
            GUILayout.EndHorizontal();
        }

        //GUILayout.BeginHorizontal();
        //NGUISettings.keepPadding = EditorGUILayout.Toggle("Keep Padding", NGUISettings.keepPadding, GUILayout.Width(100f));
        //GUILayout.Label("or replace with trimmed pixels", GUILayout.MinWidth(70f));
        //GUILayout.EndHorizontal();

                #if !UNITY_5_6
        GUILayout.BeginHorizontal();
        NGUISettings.unityPacking = EditorGUILayout.Toggle("Unity Packer", NGUISettings.unityPacking, GUILayout.Width(100f));
        GUILayout.Label("or custom packer", GUILayout.MinWidth(70f));
        GUILayout.EndHorizontal();
                #endif

        GUILayout.BeginHorizontal();
        NGUISettings.trueColorAtlas = EditorGUILayout.Toggle("Truecolor", NGUISettings.trueColorAtlas, GUILayout.Width(100f));
        GUILayout.Label("force ARGB32 textures", GUILayout.MinWidth(70f));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        NGUISettings.autoUpgradeSprites = EditorGUILayout.Toggle("Auto-upgrade", NGUISettings.autoUpgradeSprites, GUILayout.Width(100f));
        GUILayout.Label("replace textures with sprites", GUILayout.MinWidth(70f));
        GUILayout.EndHorizontal();

                #if !UNITY_5_6
        if (!NGUISettings.unityPacking)
        {
            GUILayout.BeginHorizontal();
            NGUISettings.forceSquareAtlas = EditorGUILayout.Toggle("Force Square", NGUISettings.forceSquareAtlas, GUILayout.Width(100f));
            GUILayout.Label("if on, forces a square atlas texture", GUILayout.MinWidth(70f));
            GUILayout.EndHorizontal();
        }
                #endif

#if UNITY_IPHONE || UNITY_ANDROID
        GUILayout.BeginHorizontal();
        NGUISettings.allow4096 = EditorGUILayout.Toggle("4096x4096", NGUISettings.allow4096, GUILayout.Width(100f));
        GUILayout.Label("if off, limit atlases to 2048x2048");
        GUILayout.EndHorizontal();
#endif
        NGUIEditorTools.EndContents();

        if (NGUISettings.atlas != null)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Space(20f);

            if (textures.Count > 0)
            {
                update = GUILayout.Button("Add/Update");
            }
            else if (GUILayout.Button("View Sprites"))
            {
                SpriteSelector.ShowSelected();
            }

            GUILayout.Space(20f);
            GUILayout.EndHorizontal();
        }
        else
        {
            EditorGUILayout.HelpBox("You can create a new atlas by selecting one or more textures in the Project View window, then clicking \"Create\".", MessageType.Info);

            EditorGUI.BeginDisabledGroup(textures.Count == 0);
            GUILayout.BeginHorizontal();
            GUILayout.Space(20f);
            bool create = GUILayout.Button("Create");
            GUILayout.Space(20f);
            GUILayout.EndHorizontal();
            EditorGUI.EndDisabledGroup();

            if (create)
            {
                string path = EditorUtility.SaveFilePanelInProject("Save As",
                                                                   "New Atlas.prefab", "prefab", "Save atlas as...", NGUISettings.currentPath);

                if (!string.IsNullOrEmpty(path))
                {
                    NGUISettings.currentPath = System.IO.Path.GetDirectoryName(path);
                    GameObject go      = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
                    string     matPath = path.Replace(".prefab", ".mat");
                    replace = true;

                    // Try to load the material
                    Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

                    // If the material doesn't exist, create it
                    if (mat == null)
                    {
                        Shader shader = Shader.Find(NGUISettings.atlasPMA ? "Unlit/Premultiplied Colored" : "Unlit/Transparent Colored");
                        mat = new Material(shader);

                        // Save the material
                        AssetDatabase.CreateAsset(mat, matPath);
                        AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

                        // Load the material so it's usable
                        mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
                    }

                    // Create a new prefab for the atlas
                    Object prefab = (go != null) ? go : PrefabUtility.CreateEmptyPrefab(path);

                    // Create a new game object for the atlas
                    string atlasName = path.Replace(".prefab", "");
                    atlasName = atlasName.Substring(path.LastIndexOfAny(new char[] { '/', '\\' }) + 1);
                    go        = new GameObject(atlasName);
                    go.AddComponent <UIAtlas>().spriteMaterial = mat;

                    // Update the prefab
                    PrefabUtility.ReplacePrefab(go, prefab);
                    DestroyImmediate(go);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

                    // Select the atlas
                    go = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
                    NGUISettings.atlas         = go.GetComponent <UIAtlas>();
                    Selection.activeGameObject = go;
                }
            }
        }

        string selection = null;
        Dictionary <string, int> spriteList = GetSpriteList(textures);

        if (spriteList.Count > 0)
        {
            NGUIEditorTools.DrawHeader("Sprites", true);
            {
                GUILayout.BeginHorizontal();
                GUILayout.Space(3f);
                GUILayout.BeginVertical();

                mScroll = GUILayout.BeginScrollView(mScroll);

                bool delete = false;
                int  index  = 0;
                foreach (KeyValuePair <string, int> iter in spriteList)
                {
                    ++index;

                    GUILayout.Space(-1f);
                    bool highlight = (UIAtlasInspector.instance != null) && (NGUISettings.selectedSprite == iter.Key);
                    GUI.backgroundColor = highlight ? Color.white : new Color(0.8f, 0.8f, 0.8f);
                    GUILayout.BeginHorizontal(NGUIEditorTools.textArea, GUILayout.MinHeight(20f));
                    GUI.backgroundColor = Color.white;
                    GUILayout.Label(index.ToString(), GUILayout.Width(24f));

                    if (GUILayout.Button(iter.Key, "OL TextField", GUILayout.Height(20f)))
                    {
                        selection = iter.Key;
                    }

                    if (iter.Value == 2)
                    {
                        GUI.color = Color.green;
                        GUILayout.Label("Add", GUILayout.Width(27f));
                        GUI.color = Color.white;
                    }
                    else if (iter.Value == 1)
                    {
                        GUI.color = Color.cyan;
                        GUILayout.Label("Update", GUILayout.Width(45f));
                        GUI.color = Color.white;
                    }
                    else
                    {
                        if (mDelNames.Contains(iter.Key))
                        {
                            GUI.backgroundColor = Color.red;

                            if (GUILayout.Button("Delete", GUILayout.Width(60f)))
                            {
                                delete = true;
                            }
                            GUI.backgroundColor = Color.green;
                            if (GUILayout.Button("X", GUILayout.Width(22f)))
                            {
                                mDelNames.Remove(iter.Key);
                                delete = false;
                            }
                            GUI.backgroundColor = Color.white;
                        }
                        else
                        {
                            // If we have not yet selected a sprite for deletion, show a small "X" button
                            if (GUILayout.Button("X", GUILayout.Width(22f)))
                            {
                                mDelNames.Add(iter.Key);
                            }
                        }
                    }
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndScrollView();
                GUILayout.EndVertical();
                GUILayout.Space(3f);
                GUILayout.EndHorizontal();

                // If this sprite was marked for deletion, remove it from the atlas
                if (delete)
                {
                    List <SpriteEntry> sprites = new List <SpriteEntry>();
                    ExtractSprites(NGUISettings.atlas, sprites);

                    for (int i = sprites.Count; i > 0;)
                    {
                        SpriteEntry ent = sprites[--i];
                        if (mDelNames.Contains(ent.name))
                        {
                            sprites.RemoveAt(i);
                        }
                    }
                    UpdateAtlas(NGUISettings.atlas, sprites);
                    mDelNames.Clear();
                    NGUIEditorTools.RepaintSprites();
                }
                else if (update)
                {
                    UpdateAtlas(textures, true);
                }
                else if (replace)
                {
                    UpdateAtlas(textures, false);
                }

                if (NGUISettings.atlas != null && !string.IsNullOrEmpty(selection))
                {
                    NGUIEditorTools.SelectSprite(selection);
                }
                else if (NGUISettings.autoUpgradeSprites && (update || replace))
                {
                    NGUIEditorTools.UpgradeTexturesToSprites(NGUISettings.atlas);
                    NGUIEditorTools.RepaintSprites();
                }
            }
        }

        if (NGUISettings.atlas != null && textures.Count == 0)
        {
            EditorGUILayout.HelpBox("You can reveal more options by selecting one or more textures in the Project View window.", MessageType.Info);
        }

        // Uncomment this line if you want to be able to force-sort the atlas
        //if (NGUISettings.atlas != null && GUILayout.Button("Sort Alphabetically")) NGUISettings.atlas.SortAlphabetically();
    }
예제 #16
0
        private void RenderSpriteLine()
        {
            List <SpriteEntry> entries = new List <SpriteEntry>();
            int tolerance = ObjectSize ? 16 : 8;

            // Get all entries from OAM ram
            for (int i = 0; i < 40; i++)
            {
                SpriteEntry entry = new SpriteEntry();
                entry.Y          = oam[i * 4] - 16;
                entry.X          = oam[i * 4 + 1] - 8;
                entry.TileNumber = oam[i * 4 + 2];
                entry.Attributes = oam[i * 4 + 3];
                entry.TableIndex = i;
                // Is this sprite in the renderable area?
                if (entry.X < 160 && entry.Y < 144 && entry.Y > LY - tolerance && entry.Y < LY + 1)
                {
                    entries.Add(entry);
                }
            }
            // TODO: Sort (out)
            // Render
            foreach (SpriteEntry entry in entries)
            {
                int    displacementy = LY - entry.Y;
                int    colorpalette  = entry.Attributes & 7;
                int    tilenumber    = entry.TileNumber;
                int    tilebank      = (entry.Attributes >> 3) & 1;
                int    palette       = (entry.Attributes & 0x10) == 0x10 ? OBP1 : OBP0;
                bool   flipx         = (entry.Attributes & 0x20) == 0x20;
                bool   flipy         = (entry.Attributes & 0x40) == 0x40;
                bool   behind        = (entry.Attributes & 0x80) == 0x80;
                uint[] tileline;
                if (ObjectSize)   // size is 8 * 16
                {
                    if (displacementy > 7)
                    {
                        // use the second tile
                        tilenumber    |= 1;
                        displacementy -= 8;
                    }
                    else
                    {
                        // use the first tile
                        tilenumber &= 0xFE;
                    }
                }
                if (flipy)
                {
                    displacementy = 7 - displacementy;
                }
                if (rom.HasColorFeatures)
                {
                    int attributes = colorpalette | (tilebank << 3);
                    tileline = ReadTileLineColor(tilenumber * 16, displacementy, attributes, pram2, true);
                }
                else
                {
                    tileline = ReadTileLine(tilenumber * 16, displacementy, palette, true);
                }
                if (flipx)
                {
                    Array.Reverse(tileline);
                }
                DrawTile(tileline, entry.X, LY);
            }
        }
예제 #17
0
    /// <summary>
    /// Draw the UI for this tool.
    /// </summary>

    void OnGUI()
    {
        bool create  = false;
        bool update  = false;
        bool replace = false;

        string prefabPath = "";
        string matPath    = "";

        // If we have an atlas to work with, see if we can figure out the path for it and its material
        if (NGUISettings.atlas != null && NGUISettings.atlas.name == NGUISettings.atlasName)
        {
            prefabPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.gameObject.GetInstanceID());
            if (NGUISettings.atlas.spriteMaterial != null)
            {
                matPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.spriteMaterial.GetInstanceID());
            }
        }

        // Assume default values if needed
        if (string.IsNullOrEmpty(NGUISettings.atlasName))
        {
            NGUISettings.atlasName = "New Atlas";
        }
        if (string.IsNullOrEmpty(prefabPath))
        {
            prefabPath = NGUIEditorTools.GetSelectionFolder() + NGUISettings.atlasName + ".prefab";
        }
        if (string.IsNullOrEmpty(matPath))
        {
            matPath = NGUIEditorTools.GetSelectionFolder() + NGUISettings.atlasName + ".mat";
        }

        // Try to load the prefab
        GameObject go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;

        if (NGUISettings.atlas == null && go != null)
        {
            NGUISettings.atlas = go.GetComponent <UIAtlas>();
        }

        EditorGUIUtility.LookLikeControls(80f);

        GUILayout.Space(6f);
        GUILayout.BeginHorizontal();

        if (go == null)
        {
            GUI.backgroundColor = Color.green;
            create = GUILayout.Button("Create", GUILayout.Width(76f));
        }
        else
        {
            GUI.backgroundColor = Color.red;
            create = GUILayout.Button("Replace", GUILayout.Width(76f));
        }

        GUI.backgroundColor    = Color.white;
        NGUISettings.atlasName = GUILayout.TextField(NGUISettings.atlasName);
        GUILayout.EndHorizontal();

        if (create)
        {
            // If the prefab already exists, confirm that we want to overwrite it
            if (go == null || EditorUtility.DisplayDialog("Are you sure?", "Are you sure you want to replace the contents of the " +
                                                          NGUISettings.atlasName + " atlas with the textures currently selected in the Project View? All other sprites will be deleted.", "Yes", "No"))
            {
                replace = true;

                // Try to load the material
                Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

                // If the material doesn't exist, create it
                if (mat == null)
                {
                    Shader shader = Shader.Find("Unlit/Transparent Colored");
                    mat = new Material(shader);

                    // Save the material
                    AssetDatabase.CreateAsset(mat, matPath);
                    AssetDatabase.Refresh();

                    // Load the material so it's usable
                    mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
                }

                if (NGUISettings.atlas == null || NGUISettings.atlas.name != NGUISettings.atlasName)
                {
                    // Create a new prefab for the atlas
#if UNITY_3_4
                    Object prefab = (go != null) ? go : EditorUtility.CreateEmptyPrefab(prefabPath);
#else
                    Object prefab = (go != null) ? go : PrefabUtility.CreateEmptyPrefab(prefabPath);
#endif
                    // Create a new game object for the atlas
                    go = new GameObject(NGUISettings.atlasName);
                    go.AddComponent <UIAtlas>().spriteMaterial = mat;

                    // Update the prefab
#if UNITY_3_4
                    EditorUtility.ReplacePrefab(go, prefab);
#else
                    PrefabUtility.ReplacePrefab(go, prefab);
#endif
                    DestroyImmediate(go);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();

                    // Select the atlas
                    go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                    NGUISettings.atlas = go.GetComponent <UIAtlas>();
                }
            }
        }

        ComponentSelector.Draw <UIAtlas>("Select", NGUISettings.atlas, OnSelectAtlas);

        List <Texture> textures = GetSelectedTextures();

        if (NGUISettings.atlas != null && NGUISettings.atlas.name == NGUISettings.atlasName)
        {
            Material mat = NGUISettings.atlas.spriteMaterial;
            Texture  tex = NGUISettings.atlas.texture;

            // Material information
            GUILayout.BeginHorizontal();
            {
                if (mat != null)
                {
                    if (GUILayout.Button("Material", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = mat;
                    }
                    GUILayout.Label(" " + mat.name);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Material", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();

            // Texture atlas information
            GUILayout.BeginHorizontal();
            {
                if (tex != null)
                {
                    if (GUILayout.Button("Texture", GUILayout.Width(76f)))
                    {
                        Selection.activeObject = tex;
                    }
                    GUILayout.Label(" " + tex.width + "x" + tex.height);
                }
                else
                {
                    GUI.color = Color.grey;
                    GUILayout.Button("Texture", GUILayout.Width(76f));
                    GUI.color = Color.white;
                    GUILayout.Label(" N/A");
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            NGUISettings.atlasPadding = Mathf.Clamp(EditorGUILayout.IntField("Padding", NGUISettings.atlasPadding, GUILayout.Width(100f)), 0, 8);
            GUILayout.Label("in pixels in-between of sprites");
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            NGUISettings.atlasTrimming = EditorGUILayout.Toggle("Trim Alpha", NGUISettings.atlasTrimming, GUILayout.Width(100f));
            GUILayout.Label("Remove empty space");
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            NGUISettings.unityPacking = EditorGUILayout.Toggle("Unity Packer", NGUISettings.unityPacking, GUILayout.Width(100f));
            GUILayout.Label("if off, use a custom packer");
            GUILayout.EndHorizontal();

            if (textures.Count > 0)
            {
                GUI.backgroundColor = Color.green;
                update = GUILayout.Button("Add/Update All");
                GUI.backgroundColor = Color.white;
            }
            else
            {
                NGUIEditorTools.DrawSeparator();
                GUILayout.Label("You can reveal more options by selecting\none or more textures in the Project View\nwindow.");
            }
        }
        else
        {
            NGUIEditorTools.DrawSeparator();
            GUILayout.Label("You can create a new atlas by selecting\none or more textures in the Project View\nwindow, then clicking \"Create\".");
        }

        Dictionary <string, int> spriteList = GetSpriteList(textures);

        if (spriteList.Count > 0)
        {
            NGUIEditorTools.DrawHeader("Sprites");
            GUILayout.Space(-7f);

            mScroll = GUILayout.BeginScrollView(mScroll);

            bool delete = false;
            int  index  = 0;
            foreach (KeyValuePair <string, int> iter in spriteList)
            {
                ++index;
                NGUIEditorTools.HighlightLine(new Color(0.6f, 0.6f, 0.6f));
                GUILayout.BeginHorizontal();
                GUILayout.Label(index.ToString(), GUILayout.Width(24f));
                GUILayout.Label(iter.Key);

                if (iter.Value == 2)
                {
                    GUI.color = Color.green;
                    GUILayout.Label("Add", GUILayout.Width(27f));
                    GUI.color = Color.white;
                }
                else if (iter.Value == 1)
                {
                    GUI.color = Color.cyan;
                    GUILayout.Label("Update", GUILayout.Width(45f));
                    GUI.color = Color.white;
                }
                else
                {
                    if (mDelNames.Contains(iter.Key))
                    {
                        GUI.backgroundColor = Color.red;

                        if (GUILayout.Button("Delete", GUILayout.Width(60f)))
                        {
                            delete = true;
                        }
                        GUI.backgroundColor = Color.green;
                        if (GUILayout.Button("X", GUILayout.Width(22f)))
                        {
                            mDelNames.Remove(iter.Key);
                            delete = false;
                        }
                        GUI.backgroundColor = Color.white;
                    }
                    else
                    {
                        // If we have not yet selected a sprite for deletion, show a small "X" button
                        if (GUILayout.Button("X", GUILayout.Width(22f)))
                        {
                            mDelNames.Add(iter.Key);
                        }
                    }
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.EndScrollView();

            // If this sprite was marked for deletion, remove it from the atlas
            if (delete)
            {
                List <SpriteEntry> sprites = new List <SpriteEntry>();
                ExtractSprites(NGUISettings.atlas, sprites);

                for (int i = sprites.Count; i > 0;)
                {
                    SpriteEntry ent = sprites[--i];

                    if (mDelNames.Contains(ent.tex.name))
                    {
                        sprites.RemoveAt(i);
                    }
                }
                UpdateAtlas(NGUISettings.atlas, sprites);
                mDelNames.Clear();
            }
            else if (update)
            {
                UpdateAtlas(textures, true);
            }
            else if (replace)
            {
                UpdateAtlas(textures, false);
            }
            return;
        }
    }
예제 #18
0
	/// <summary>
	/// Extract sprites from the atlas, adding them to the list.
	/// </summary>

	static public void ExtractSprites (UIAtlas atlas, List<SpriteEntry> finalSprites)
	{
		// Make the atlas texture readable
		Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false, !atlas.premultipliedAlpha);

		if (atlasTex != null)
		{
			Color32[] oldPixels = null;
			int oldWidth = atlasTex.width;
			int oldHeight = atlasTex.height;
			List<UISpriteData> existingSprites = atlas.spriteList;

			foreach (UISpriteData es in existingSprites)
			{
				bool found = false;

				foreach (SpriteEntry fs in finalSprites)
				{
					if (es.name == fs.name)
					{
						fs.CopyBorderFrom(es);
						found = true;
						break;
					}
				}

				if (!found)
				{
					// Read the atlas
					if (oldPixels == null) oldPixels = atlasTex.GetPixels32();

					int xmin = Mathf.Clamp(es.x, 0, oldWidth);
					int ymin = Mathf.Clamp(es.y, 0, oldHeight);
					int xmax = Mathf.Min(xmin + es.width, oldWidth - 1);
					int ymax = Mathf.Min(ymin + es.height, oldHeight - 1);
					int newWidth = Mathf.Clamp(es.width, 0, oldWidth);
					int newHeight = Mathf.Clamp(es.height, 0, oldHeight);

					if (newWidth == 0 || newHeight == 0) continue;

					Color32[] newPixels = new Color32[newWidth * newHeight];

					for (int y = 0; y < newHeight; ++y)
					{
						int cy = ymin + y;
						if (cy > ymax) cy = ymax;

						for (int x = 0; x < newWidth; ++x)
						{
							int cx = xmin + x;
							if (cx > xmax) cx = xmax;

							int newIndex = (newHeight - 1 - y) * newWidth + x;
							int oldIndex = (oldHeight - 1 - cy) * oldWidth + cx;

							newPixels[newIndex] = oldPixels[oldIndex];
						}
					}

					// Create a new sprite
					SpriteEntry sprite = new SpriteEntry();
					sprite.CopyFrom(es);
					sprite.SetRect(0, 0, newWidth, newHeight);
					sprite.temporaryTexture = true;
					sprite.tex = new Texture2D(newWidth, newHeight);
					sprite.tex.SetPixels32(newPixels);
					sprite.tex.Apply();
					finalSprites.Add(sprite);
				}
			}
		}

		// The atlas no longer needs to be readable
		NGUIEditorTools.ImportTexture(atlas.texture, false, false, !atlas.premultipliedAlpha);
	}
예제 #19
0
    /// <summary>
    /// Create a list of sprites using the specified list of textures.
    /// </summary>
    static List<SpriteEntry> CreateSprites(List<Texture> textures)
    {
        List<SpriteEntry> list = new List<SpriteEntry>();

        foreach (Texture tex in textures)
        {
            Texture2D oldTex = NGUIEditorTools.ImportTexture(tex, true, false);
            if (oldTex == null) continue;

            Color32[] pixels = oldTex.GetPixels32();

            int xmin = oldTex.width;
            int xmax = 0;
            int ymin = oldTex.height;
            int ymax = 0;
            int oldWidth = oldTex.width;
            int oldHeight = oldTex.height;

            for (int y = 0, yw = oldHeight; y < yw; ++y)
            {
                for (int x = 0, xw = oldWidth; x < xw; ++x)
                {
                    Color32 c = pixels[y * xw + x];

                    if (c.a != 0)
                    {
                        if (y < ymin) ymin = y;
                        if (y > ymax) ymax = y;
                        if (x < xmin) xmin = x;
                        if (x > xmax) xmax = x;
                    }
                }
            }

            int newWidth  = (xmax - xmin) + 1;
            int newHeight = (ymax - ymin) + 1;

            if (newWidth > 0 && newHeight > 0)
            {
                SpriteEntry sprite = new SpriteEntry();
                sprite.rect = new Rect(0f, 0f, oldTex.width, oldTex.height);

                if (newWidth == oldWidth && newHeight == oldHeight)
                {
                    sprite.tex = oldTex;
                    sprite.temporaryTexture = false;
                }
                else
                {
                    Color32[] newPixels = new Color32[newWidth * newHeight];

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = y * newWidth + x;
                            int oldIndex = (ymin + y) * oldWidth + (xmin + x);
                            newPixels[newIndex] = pixels[oldIndex];
                        }
                    }

                    // Create a new texture
                    sprite.temporaryTexture = true;
                    sprite.tex = new Texture2D(newWidth, newHeight);
                    sprite.tex.name = oldTex.name;
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();

                    // Remember the padding offset
                    sprite.minX = xmin;
                    sprite.maxX = oldWidth - newWidth - xmin;
                    sprite.minY = ymin;
                    sprite.maxY = oldHeight - newHeight - ymin;
                }
                list.Add(sprite);
            }
        }
        return list;
    }
예제 #20
0
	/// <summary>
	/// Add the specified texture to the atlas, or update an existing one.
	/// </summary>

	static public void AddOrUpdate (UIAtlas atlas, SpriteEntry se)
	{
		if (atlas != null && se != null)
		{
			List<SpriteEntry> sprites = new List<SpriteEntry>();
			sprites.Add(se);
			ExtractSprites(atlas, sprites);
			UpdateAtlas(atlas, sprites);
		}
	}
예제 #21
0
    /// <summary>
    /// Extract sprites from the atlas, adding them to the list.
    /// </summary>

    static void ExtractSprites(UIAtlas atlas, List <SpriteEntry> sprites)
    {
        // Make the atlas texture readable
        Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false);

        if (atlasTex != null)
        {
            atlas.coordinates = UIAtlas.Coordinates.Pixels;

            Color32[]             oldPixels = null;
            int                   oldWidth  = atlasTex.width;
            int                   oldHeight = atlasTex.height;
            List <UIAtlas.Sprite> list      = atlas.spriteList;

            foreach (UIAtlas.Sprite asp in list)
            {
                bool found = false;

                foreach (SpriteEntry se in sprites)
                {
                    if (asp.name == se.tex.name)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    // Read the atlas
                    if (oldPixels == null)
                    {
                        oldPixels = atlasTex.GetPixels32();
                    }

                    Rect rect = asp.outer;
                    rect.xMin = Mathf.Clamp(rect.xMin, 0f, oldWidth);
                    rect.yMin = Mathf.Clamp(rect.yMin, 0f, oldHeight);
                    rect.xMax = Mathf.Clamp(rect.xMax, 0f, oldWidth);
                    rect.yMax = Mathf.Clamp(rect.yMax, 0f, oldHeight);

                    int newWidth  = Mathf.RoundToInt(rect.width);
                    int newHeight = Mathf.RoundToInt(rect.height);
                    if (newWidth == 0 || newHeight == 0)
                    {
                        continue;
                    }

                    Color32[] newPixels = new Color32[newWidth * newHeight];
                    int       xmin      = Mathf.RoundToInt(rect.x);
                    int       ymin      = Mathf.RoundToInt(oldHeight - rect.yMax);

                    for (int y = 0; y < newHeight; ++y)
                    {
                        for (int x = 0; x < newWidth; ++x)
                        {
                            int newIndex = y * newWidth + x;
                            int oldIndex = (ymin + y) * oldWidth + (xmin + x);
                            newPixels[newIndex] = oldPixels[oldIndex];
                        }
                    }

                    // Create a new sprite
                    SpriteEntry sprite = new SpriteEntry();
                    sprite.temporaryTexture = true;
                    sprite.tex      = new Texture2D(newWidth, newHeight);
                    sprite.tex.name = asp.name;
                    sprite.rect     = new Rect(0f, 0f, newWidth, newHeight);
                    sprite.tex.SetPixels32(newPixels);
                    sprite.tex.Apply();

                    // Min/max coordinates are in pixels
                    sprite.minX = Mathf.RoundToInt(asp.paddingLeft * newWidth);
                    sprite.maxX = Mathf.RoundToInt(asp.paddingRight * newWidth);
                    sprite.minY = Mathf.RoundToInt(asp.paddingBottom * newHeight);
                    sprite.maxY = Mathf.RoundToInt(asp.paddingTop * newHeight);

                    sprites.Add(sprite);
                }
            }
        }

        // The atlas no longer needs to be readable
        NGUIEditorTools.ImportTexture(atlas.texture, false, false);
    }
예제 #22
0
	/// <summary>
	/// Extract sprites from the atlas, adding them to the list.
	/// </summary>

	static void ExtractSprites (UIAtlas atlas, List<SpriteEntry> sprites)
	{
		// Make the atlas texture readable
		Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false);

		if (atlasTex != null)
		{
			atlas.coordinates = UIAtlas.Coordinates.Pixels;

			Color32[] oldPixels = null;
			int oldWidth = atlasTex.width;
			int oldHeight = atlasTex.height;
			List<UIAtlas.Sprite> list = atlas.spriteList;

			foreach (UIAtlas.Sprite asp in list)
			{
				bool found = false;

				foreach (SpriteEntry se in sprites)
				{
					if (asp.name == se.tex.name)
					{
						found = true;
						break;
					}
				}

				if (!found)
				{
					// Read the atlas
					if (oldPixels == null) oldPixels = atlasTex.GetPixels32();

					Rect rect = asp.outer;
					rect.xMin = Mathf.Clamp(rect.xMin, 0f, oldWidth);
					rect.yMin = Mathf.Clamp(rect.yMin, 0f, oldHeight);
					rect.xMax = Mathf.Clamp(rect.xMax, 0f, oldWidth);
					rect.yMax = Mathf.Clamp(rect.yMax, 0f, oldHeight);

					int newWidth = Mathf.RoundToInt(rect.width);
					int newHeight = Mathf.RoundToInt(rect.height);
					if (newWidth == 0 || newHeight == 0) continue;

					Color32[] newPixels = new Color32[newWidth * newHeight];
					int xmin = Mathf.RoundToInt(rect.x);
					int ymin = Mathf.RoundToInt(oldHeight - rect.yMax);

					for (int y = 0; y < newHeight; ++y)
					{
						for (int x = 0; x < newWidth; ++x)
						{
							int newIndex = y * newWidth + x;
							int oldIndex = (ymin + y) * oldWidth + (xmin + x);
							newPixels[newIndex] = oldPixels[oldIndex];
						}
					}

					// Create a new sprite
					SpriteEntry sprite = new SpriteEntry();
					sprite.temporaryTexture = true;
					sprite.tex = new Texture2D(newWidth, newHeight);
					sprite.tex.name = asp.name;
					sprite.rect = new Rect(0f, 0f, newWidth, newHeight);
					sprite.tex.SetPixels32(newPixels);
					sprite.tex.Apply();

					// Min/max coordinates are in pixels
					sprite.minX = Mathf.RoundToInt(asp.paddingLeft * newWidth);
					sprite.maxX = Mathf.RoundToInt(asp.paddingRight * newWidth);
					sprite.minY = Mathf.RoundToInt(asp.paddingBottom * newHeight);
					sprite.maxY = Mathf.RoundToInt(asp.paddingTop * newHeight);

					sprites.Add(sprite);
				}
			}
		}

		// The atlas no longer needs to be readable
		NGUIEditorTools.ImportTexture(atlas.texture, false, false);
	}
    private void FindAllEntries(BuildTarget buildTarget,
                                List <SpriteEntry> spriteEntries, List <AtlasEntry> atlasEntries)
    {
        var platformString = GetPlatformString(buildTarget);

        foreach (var guid in AssetDatabase.FindAssets("t:Texture"))
        {
            var path     = AssetDatabase.GUIDToAssetPath(guid);
            var importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer == null)
            {
                continue;
            }

            // 获取sprite列表
            var sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(path)
                          .Distinct()
                          .OfType <Sprite>()
                          .Where(x => x.packed)
                          .ToArray();
            for (var i = 0; i < sprites.Length; ++i)
            {
                var       sprite = sprites[i];
                Texture2D atlasTexture;
                string    atlasName;
                Packer.GetAtlasDataForSprite(sprite, out atlasName, out atlasTexture);

                if (atlasTexture != null)
                {
                    var entry = new SpriteEntry
                    {
                        Path         = path,
                        Sprite       = sprite,
                        Importer     = importer,
                        Texture      = SpriteUtility.GetSpriteTexture(sprite, false),
                        AtlasName    = atlasName,
                        Uvs          = SpriteUtility.GetSpriteUVs(sprite, false),
                        AtlasUvs     = SpriteUtility.GetSpriteUVs(sprite, true),
                        AtlasTexture = atlasTexture,
                    };
                    spriteEntries.Add(entry);
                }
            }
        }

        // 获取atlas列表
        var atlasGroups =
            from e in spriteEntries
            group e by e.AtlasTexture;

        foreach (var atlasGroup in atlasGroups)
        {
            var tex     = atlasGroup.Key;
            var texName = tex.name;

            // 检查是否需要分离alpha通道
            var atlasName         = string.Empty;
            var needSeparateAlpha = false;
            foreach (var spriteEntry in atlasGroup)
            {
                var importer = spriteEntry.Importer;
                atlasName = importer.spritePackingTag;
                if (!string.IsNullOrEmpty(atlasName))
                {
                    var settings = importer.GetPlatformTextureSettings(platformString);
                    var format   = settings.format;
                    if (format == TextureImporterFormat.Automatic)
                    {
                        format = importer.GetAutomaticFormat(platformString);
                    }
                    needSeparateAlpha = TextureUtility.IsTransparent(format);
                }
            }

            if (CustomAtlasConfig.ShouldKeepAlpha(atlasName))
            {
                needSeparateAlpha = false;
            }

            var entry = new AtlasEntry
            {
                Name              = texName,
                Texture           = tex,
                SpriteEntries     = atlasGroup.ToList(),
                NeedSeparateAlpha = needSeparateAlpha,
            };
            atlasEntries.Add(entry);
        }
    }