Last active
April 22, 2024 14:10
-
-
Save chrisyarbrough/a15930f1831e0c8b543ff4bf518a83ed to your computer and use it in GitHub Desktop.
Demonstrates how to copy and import Unity's standard UI sprites into a project. This can be useful if the builtin sprites need to be modified or placed onto an atlas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.IO; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
using UnityEngine.UI; | |
public static class ExportBuiltinUISprites | |
{ | |
private const string outputDirectory = "Assets/Graphics/"; | |
[MenuItem("Tools/Export Builtin UI Sprites")] | |
public static void Export() | |
{ | |
List<SpriteImportInfo> importedAssets; | |
try | |
{ | |
AssetDatabase.StartAssetEditing(); | |
importedAssets = CreateTextureAssets(); | |
} | |
finally | |
{ | |
AssetDatabase.StopAssetEditing(); | |
} | |
if (importedAssets == null) | |
return; | |
try | |
{ | |
AssetDatabase.StartAssetEditing(); | |
ApplySpriteImportSettings(importedAssets); | |
} | |
finally | |
{ | |
AssetDatabase.StopAssetEditing(); | |
} | |
} | |
private static IEnumerable<string> StandardResources() | |
{ | |
yield return "UI/Skin/UISprite.psd"; | |
yield return "UI/Skin/Background.psd"; | |
yield return "UI/Skin/InputFieldBackground.psd"; | |
yield return "UI/Skin/Knob.psd"; | |
yield return "UI/Skin/Checkmark.psd"; | |
yield return "UI/Skin/DropdownArrow.psd"; | |
yield return "UI/Skin/UIMask.psd"; | |
} | |
private static List<SpriteImportInfo> CreateTextureAssets() | |
{ | |
var assetInfo = new List<SpriteImportInfo>(); | |
foreach (var path in StandardResources()) | |
{ | |
Sprite sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(path); | |
string outputPath = ExportBuiltinUISprites.outputDirectory + sprite.name + ".png"; | |
assetInfo.Add(new SpriteImportInfo(sprite, outputPath)); | |
var texture = CreateReadableCopy(sprite.texture); | |
var bytes = texture.EncodeToPNG(); | |
File.WriteAllBytes(outputPath, bytes); | |
AssetDatabase.ImportAsset( | |
outputPath, | |
ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport); | |
} | |
return assetInfo; | |
} | |
private static Texture2D CreateReadableCopy(Texture2D texture) | |
{ | |
var bytes = texture.GetRawTextureData(); | |
var copy = new Texture2D(texture.width, texture.height); | |
copy.LoadRawTextureData(bytes); | |
return copy; | |
} | |
private static void ApplySpriteImportSettings(List<SpriteImportInfo> importedAssets) | |
{ | |
for (var i = 0; i < importedAssets.Count; i++) | |
{ | |
Sprite sprite = importedAssets[i].Sprite; | |
var importer = AssetImporter.GetAtPath(importedAssets[i].Path); | |
var textureImporter = importer as TextureImporter; | |
textureImporter.textureCompression = TextureImporterCompression.Uncompressed; | |
textureImporter.spriteBorder = sprite.border; | |
textureImporter.spritePixelsPerUnit = sprite.pixelsPerUnit; | |
textureImporter.spritePivot = sprite.pivot; | |
textureImporter.spriteImportMode = SpriteImportMode.Multiple; | |
textureImporter.spritesheet = new[] | |
{ | |
new SpriteMetaData | |
{ | |
rect = sprite.rect, name = sprite.name, border = sprite.border | |
} | |
}; | |
var settings = new TextureImporterSettings(); | |
textureImporter.ReadTextureSettings(settings); | |
settings.spriteMeshType = SpriteMeshType.FullRect; | |
settings.spriteGenerateFallbackPhysicsShape = false; | |
textureImporter.SetTextureSettings(settings); | |
textureImporter.SaveAndReimport(); | |
} | |
} | |
private readonly struct SpriteImportInfo | |
{ | |
public readonly Sprite Sprite; | |
public readonly string Path; | |
public SpriteImportInfo(in Sprite sprite, in string path) | |
{ | |
this.Sprite = sprite; | |
this.Path = path; | |
} | |
} | |
[MenuItem("Tools/Replace builtin sprites in scene")] | |
public static void ReplaceInScene() | |
{ | |
var scene = SceneManager.GetActiveScene(); | |
var roots = scene.GetRootGameObjects(); | |
foreach (GameObject root in roots) | |
{ | |
foreach (var image in root.GetComponentsInChildren<Image>(includeInactive: true)) | |
{ | |
if (image.sprite == null) | |
continue; | |
string name = image.sprite.name; | |
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(outputDirectory + name + ".png"); | |
if (sprite != null) | |
{ | |
Undo.RecordObject(image, "Replace Sprite"); | |
image.sprite = sprite; | |
Debug.Log("Replaced: " + image.name, image); | |
} | |
else | |
{ | |
Debug.Log("Not found: " + image.name, image); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment