internal static bool rebuildAtlas( dfAtlas atlas ) { try { EditorUtility.DisplayProgressBar( "Rebuilding Texture Atlas", "Processing changes to the texture atlas...", 0 ); var sprites = atlas.Items .Where( i => i != null && !i.deleted ) .Select( i => new { source = i, texture = getTexture( i.textureGUID ) } ) .Where( i => i.texture != null ) .OrderByDescending( i => i.texture.width * i.texture.height ) .ToList(); var textures = sprites.Select( i => i.texture ).ToList(); var oldAtlasTexture = atlas.Material.mainTexture; var texturePath = AssetDatabase.GetAssetPath( oldAtlasTexture ); var padding = EditorPrefs.GetInt( "DaikonForge.AtlasDefaultPadding", 2 ); var newAtlasTexture = new Texture2D( 0, 0, TextureFormat.RGBA32, false ); var newRects = newAtlasTexture.PackTextures2( textures.ToArray(), padding, dfTextureAtlasInspector.MaxAtlasSize, dfTextureAtlasInspector.ForceSquare ); byte[] bytes = newAtlasTexture.EncodeToPNG(); System.IO.File.WriteAllBytes( texturePath, bytes ); bytes = null; DestroyImmediate( newAtlasTexture ); setAtlasTextureSettings( texturePath, false ); // Fix up the new sprite locations for( int i = 0; i < sprites.Count; i++ ) { sprites[ i ].source.region = newRects[ i ]; sprites[ i ].source.sizeInPixels = new Vector2( textures[ i ].width, textures[ i ].height ); sprites[ i ].source.texture = null; } // Remove any deleted sprites atlas.Items.RemoveAll( i => i.deleted ); // Re-sort the Items collection atlas.Items.Sort(); atlas.RebuildIndexes(); EditorUtility.SetDirty( atlas ); EditorUtility.SetDirty( atlas.Material ); dfGUIManager.RefreshAll( true ); return true; } catch( Exception err ) { Debug.LogError( err.ToString(), atlas ); EditorUtility.DisplayDialog( "Error Rebuilding Texture Atlas", err.Message, "OK" ); return false; } finally { EditorUtility.ClearProgressBar(); } }
public static void CreateAtlasFromSelection() { try { EditorUtility.DisplayProgressBar( "Creating Texture Atlas", "Adding selected textures to the Texture Atlas", 0 ); var selection = Selection .GetFiltered( typeof( Texture2D ), SelectionMode.Assets ) .Cast<Texture2D>() .Where( t => isReadable( t ) ) .OrderByDescending( t => t.width * t.height ) .ToArray(); if( selection.Length == 0 ) { EditorUtility.DisplayDialog( "Create Texture Atlas", "Either no textures selected or none of the selected textures has Read/Write enabled", "OK" ); return; } var saveFolder = Path.GetDirectoryName( AssetDatabase.GetAssetPath( selection[ 0 ] ) ); var prefabPath = EditorUtility.SaveFilePanel( "Create Texture Atlas", saveFolder, "Texture Atlas", "prefab" ); if( string.IsNullOrEmpty( prefabPath ) ) return; prefabPath = prefabPath.MakeRelativePath(); var padding = EditorPrefs.GetInt( "DaikonForge.AtlasDefaultPadding", 2 ); var texture = new Texture2D( 1, 1, TextureFormat.ARGB32, false ); var rects = texture.PackTextures2( selection, padding, dfTextureAtlasInspector.MaxAtlasSize, dfTextureAtlasInspector.ForceSquare ); var texturePath = Path.ChangeExtension( prefabPath, "png" ); byte[] bytes = texture.EncodeToPNG(); System.IO.File.WriteAllBytes( texturePath, bytes ); bytes = null; DestroyImmediate( texture ); setAtlasTextureSettings( texturePath, true ); texture = AssetDatabase.LoadAssetAtPath( texturePath, typeof( Texture2D ) ) as Texture2D; if( texture == null ) Debug.LogError( "Failed to find texture at " + texturePath ); var sprites = new List<dfAtlas.ItemInfo>(); for( int i = 0; i < rects.Length; i++ ) { var pixelCoords = rects[ i ]; var size = new Vector2( selection[ i ].width, selection[ i ].height ); var spritePath = AssetDatabase.GetAssetPath( selection[ i ] ); var guid = AssetDatabase.AssetPathToGUID( spritePath ); var item = new dfAtlas.ItemInfo() { name = selection[ i ].name, region = pixelCoords, rotated = false, textureGUID = guid, sizeInPixels = size }; sprites.Add( item ); } sprites.Sort(); var shader = Shader.Find( "Daikon Forge/Default UI Shader" ); var atlasMaterial = new Material( shader ); atlasMaterial.mainTexture = texture; AssetDatabase.CreateAsset( atlasMaterial, Path.ChangeExtension( texturePath, "mat" ) ); var go = new GameObject() { name = Path.GetFileNameWithoutExtension( prefabPath ) }; var atlas = go.AddComponent<dfAtlas>(); atlas.Material = atlasMaterial; atlas.AddItems( sprites ); var prefab = PrefabUtility.CreateEmptyPrefab( prefabPath ); prefab.name = atlas.name; PrefabUtility.ReplacePrefab( go, prefab ); DestroyImmediate( go ); AssetDatabase.Refresh(); #region Delay execution of object selection to work around a Unity issue // Declared with null value to eliminate "uninitialized variable" // compiler error in lambda below. EditorApplication.CallbackFunction callback = null; callback = () => { EditorUtility.FocusProjectWindow(); go = AssetDatabase.LoadMainAssetAtPath( prefabPath ) as GameObject; Selection.objects = new Object[] { go }; EditorGUIUtility.PingObject( go ); Debug.Log( "Texture Atlas prefab created at " + prefabPath, prefab ); EditorApplication.delayCall -= callback; }; EditorApplication.delayCall += callback; #endregion } catch( Exception err ) { Debug.LogError( err.ToString() ); EditorUtility.DisplayDialog( "Error Creating Texture Atlas", err.Message, "OK" ); } finally { EditorUtility.ClearProgressBar(); } }