Skip to content

Commit

Permalink
preserve existing settings (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus authored Apr 15, 2022
1 parent 038a83c commit 1129ddf
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 23 deletions.
8 changes: 5 additions & 3 deletions Assets/SpriteDicing/Editor/Editors/AtlasBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ private List<DicedTexture> DiceTextures (IReadOnlyList<SourceTexture> sourceText
private List<AtlasTexture> PackTextures (IReadOnlyList<DicedTexture> dicedTextures)
{
DisplayProgressBar("Packing dices...", .5f);
var settings = new TextureSettings();
settings.TryImportExisting(TexturesProperty.GetArrayElementAtIndex(0).objectReferenceValue as Texture);
DeleteAtlasTextures();
var basePath = atlasPath.Substring(0, atlasPath.LastIndexOf(".", StringComparison.Ordinal));
var textureSerializer = new TextureSerializer(basePath);
var texturePacker = new TexturePacker(textureSerializer, UVInset, ForceSquare, AtlasSizeLimit, UnitSize, Padding);
var atlasTextures = texturePacker.Pack(dicedTextures);
var serializer = new TextureSerializer(basePath, settings);
var packer = new TexturePacker(serializer, UVInset, ForceSquare, AtlasSizeLimit, UnitSize, Padding);
var atlasTextures = packer.Pack(dicedTextures);
SaveAtlasTextures();
return atlasTextures;

Expand Down
17 changes: 8 additions & 9 deletions Assets/SpriteDicing/Editor/Processors/TextureSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ namespace SpriteDicing
public class TextureSerializer : ITextureSerializer
{
private readonly string basePath;
private readonly TextureSettings settings;

public TextureSerializer (string basePath)
public TextureSerializer (string basePath, TextureSettings settings)
{
this.basePath = basePath;
this.settings = settings;
}

public Texture2D Serialize (Texture2D texture)
{
var filePath = BuildFilePath();
SaveAsPNG(texture, filePath);
var png = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
var maxSize = Mathf.Max(texture.width, texture.height);
ApplyImportSettings(filePath, Mathf.NextPowerOfTwo(maxSize));
var maxSize = Mathf.NextPowerOfTwo(Mathf.Max(texture.width, texture.height));
ApplyImportSettings(filePath, maxSize);
Object.DestroyImmediate(texture);
return png;
}
Expand All @@ -35,7 +37,7 @@ private string BuildFilePath ()
return path;
}

private static void SaveAsPNG (Texture2D texture, string filePath)
private void SaveAsPNG (Texture2D texture, string filePath)
{
var bytes = texture.EncodeToPNG();
using (var fileStream = File.Create(filePath))
Expand All @@ -44,13 +46,10 @@ private static void SaveAsPNG (Texture2D texture, string filePath)
AssetDatabase.Refresh();
}

private static void ApplyImportSettings (string filePath, int maxSize)
private void ApplyImportSettings (string filePath, int maxSize)
{
var importer = (TextureImporter)AssetImporter.GetAtPath(filePath);
importer.textureType = TextureImporterType.Default;
importer.alphaIsTransparency = true;
importer.mipmapEnabled = false;
importer.textureCompression = TextureImporterCompression.Uncompressed;
settings.ApplyExistingOrDefault(importer);
importer.maxTextureSize = maxSize;
AssetDatabase.ImportAsset(filePath);
}
Expand Down
74 changes: 74 additions & 0 deletions Assets/SpriteDicing/Editor/Processors/TextureSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace SpriteDicing
{
public class TextureSettings
{
private const string defaultPlatformId = "default";
private static readonly string[] platformIds = GetPlatformIds();
private readonly TextureImporterSettings @base = new TextureImporterSettings();
private readonly Dictionary<string, TextureImporterPlatformSettings> platforms =
new Dictionary<string, TextureImporterPlatformSettings>();

public void TryImportExisting (Texture texture)
{
if (!TryGetTextureImporter(texture, out var importer)) return;
importer.ReadTextureSettings(@base);
foreach (var platformId in platformIds)
platforms[platformId] = importer.GetPlatformTextureSettings(platformId);
platforms[defaultPlatformId] = importer.GetDefaultPlatformTextureSettings();
}

public void ApplyExistingOrDefault (TextureImporter importer)
{
if (platforms.Count == 0) ApplyDefault(importer);
else ApplyExisting(importer);
}

private bool TryGetTextureImporter (Texture texture, out TextureImporter importer)
{
var assetPath = AssetDatabase.GetAssetPath(texture);
importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
return importer != null;
}

private void ApplyDefault (TextureImporter importer)
{
importer.textureType = TextureImporterType.Default;
importer.alphaIsTransparency = true;
importer.mipmapEnabled = false;
importer.textureCompression = TextureImporterCompression.Uncompressed;
}

private void ApplyExisting (TextureImporter importer)
{
importer.SetTextureSettings(@base);
foreach (var kv in platforms)
if (kv.Key == defaultPlatformId || kv.Value.overridden)
importer.SetPlatformTextureSettings(kv.Value);
}

[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
private static string[] GetPlatformIds ()
{
// https://github.com/Unity-Technologies/UnityCsReference/blob/2019.4/Editor/Mono/BuildPipeline/BuildPlatform.cs

Type platformsType = default, platformType = default;
foreach (var type in Assembly.GetAssembly(typeof(Editor)).GetTypes())
if (type.Name == "BuildPlatforms") platformsType = type;
else if (type.Name == "BuildPlatform") platformType = type;
else if (platformsType != null && platformType != null) break;
var platformsInstance = platformsType.GetProperty("instance").GetValue(null);
var validPlatforms = (IEnumerable<object>)platformsType
.GetMethod("GetValidPlatforms", Array.Empty<Type>())
.Invoke(platformsInstance, null);
return validPlatforms.Select(p => (string)platformType.GetField("name").GetValue(p)).ToArray();
}
}
}
3 changes: 3 additions & 0 deletions Assets/SpriteDicing/Editor/Processors/TextureSettings.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Assets/SpriteDicing/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "com.elringus.spritedicing",
"version": "1.6.1",
"version": "1.7.0",
"displayName": "SpriteDicing",
"description": "Unity extension for reusing sprite texture areas.",
"description": "Allows dicing sprite textures into atlases to eliminate identical parts.",
"unity": "2019.4",
"author": {
"name": "Elringus",
"url": "https://elringus.me"
"url": "https://github.com/Elringus"
}
}
69 changes: 67 additions & 2 deletions Assets/Tests/Editor/TextureSerializerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ public class TextureSerializerTest
private const string tempRoot = Helpers.TextureFolderPath + "/" + tempFolder;

private string basePath;
private TextureSettings textureSettings;
private TextureSerializer serializer;

[SetUp]
public void SetUp ()
{
AssetDatabase.CreateFolder(Helpers.TextureFolderPath, tempFolder);
basePath = $"{tempRoot}/{Guid.NewGuid():N}";
serializer = new TextureSerializer(basePath);
textureSettings = new TextureSettings();
serializer = new TextureSerializer(basePath, textureSettings);
}

[TearDown]
Expand All @@ -46,7 +48,7 @@ public void SerializedEqualsOriginalTexture ()
}

[Test]
public void ImportSettingsAreApplied ()
public void DefaultImportSettingsAreApplied ()
{
var importer = GetImporter(Serialize());
AreEqual(TextureImporterType.Default, importer.textureType);
Expand All @@ -56,6 +58,69 @@ public void ImportSettingsAreApplied ()
AreEqual(1, importer.maxTextureSize);
}

[Test]
public void ExistingImportSettingsArePreserved ()
{
var otherTexture = Serialize();
var otherImporter = GetImporter(otherTexture);
otherImporter.alphaIsTransparency = false;
otherImporter.textureCompression = TextureImporterCompression.Compressed;
otherImporter.SaveAndReimport();

textureSettings.TryImportExisting(otherTexture);
var importer = GetImporter(Serialize());
IsFalse(importer.alphaIsTransparency);
AreEqual(TextureImporterCompression.Compressed, importer.textureCompression);
}

[Test]
public void ExistingPlatformSpecificSettingsArePreserved ()
{
var otherPlatform = "Standalone";
var otherTexture = Serialize();
var otherImporter = GetImporter(otherTexture);
var otherSettings = new TextureImporterPlatformSettings {
name = otherPlatform,
overridden = true,
textureCompression = TextureImporterCompression.Compressed
};
otherImporter.SetPlatformTextureSettings(otherSettings);
otherImporter.SaveAndReimport();

textureSettings.TryImportExisting(otherTexture);
var importer = GetImporter(Serialize());
var settings = importer.GetPlatformTextureSettings(otherPlatform);
AreEqual(TextureImporterCompression.Compressed, settings.textureCompression);
}

[Test]
public void NonOverriddenPlatformSpecificSettingsAreIgnored ()
{
var otherPlatform = "Standalone";
var otherTexture = Serialize();
var otherImporter = GetImporter(otherTexture);
var otherSettings = new TextureImporterPlatformSettings {
name = otherPlatform,
overridden = false,
textureCompression = TextureImporterCompression.Compressed
};
otherImporter.SetPlatformTextureSettings(otherSettings);
otherImporter.SaveAndReimport();

textureSettings.TryImportExisting(otherTexture);
var importer = GetImporter(Serialize());
var settings = importer.GetPlatformTextureSettings(otherPlatform);
AreEqual(TextureImporterCompression.Uncompressed, settings.textureCompression);
}

[Test]
public void SettingsFromInvalidObjectAreIgnored ()
{
var obj = new UnityEngine.Object();
textureSettings.TryImportExisting(obj as Texture);
DoesNotThrow(() => Serialize());
}

[Test]
public void MultipleTexturesNamedCorrectly ()
{
Expand Down
8 changes: 4 additions & 4 deletions Packages/manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"dependencies": {
"com.unity.modules.imgui": "1.0.0",
"com.unity.ugui": "1.0.0",
"com.unity.2d.sprite": "1.0.0",
"com.unity.test-framework": "1.1.30",
"com.unity.ide.rider": "3.0.13",
"com.unity.test-framework": "1.1.31",
"com.unity.testtools.codecoverage": "1.1.1",
"com.unity.ide.rider": "3.0.12"
"com.unity.ugui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
}
4 changes: 2 additions & 2 deletions Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.12",
"version": "3.0.13",
"depth": 0,
"source": "registry",
"dependencies": {
Expand All @@ -30,7 +30,7 @@
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.30",
"version": "1.1.31",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down
Binary file modified SpriteDicing.unitypackage
Binary file not shown.

0 comments on commit 1129ddf

Please sign in to comment.