// MIT License - Copyright (c) 2026 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Editor.Sprites { #if UNITY_EDITOR using System; using UnityEngine; /// /// JSON-serializable configuration for sprite sheet extraction settings. /// Stored alongside sprite sheet textures as {texturePath}.spritesheet.json. /// [Serializable] public sealed class SpriteSheetConfig { /// /// Configuration file extension (without the leading dot). /// public const string FileExtension = "spritesheet.json"; /// /// Current configuration version for migration support. /// public const int CurrentVersion = 3; /// /// Configuration version number for future migration support. /// public int version = CurrentVersion; /// /// The pivot mode for extracted sprites. /// public PivotMode pivotMode = PivotMode.Center; /// /// Custom pivot point when pivotMode is set to Custom. /// Values are normalized (0-1) where (0,0) is bottom-left and (1,1) is top-right. /// public Vector2 customPivot = new(0.5f, 0.5f); /// /// The auto-detection algorithm to use. /// Stored as int for JSON serialization compatibility. /// public int algorithm = (int)AutoDetectionAlgorithm.AutoBest; /// /// Expected number of sprites in the sheet. -1 indicates not set. /// Used for validation and uniform grid detection. /// public int expectedSpriteCount = -1; /// /// SHA256 hash of the texture file bytes for change detection. /// When the texture content changes, this hash will no longer match, /// indicating the configuration may be stale. /// public string textureContentHash; /// /// Cached algorithm results for this texture. /// Invalidated when textureContentHash changes. /// public CachedAlgorithmResult cachedAlgorithmResult; /// /// Whether to snap detected cell sizes to exact divisors of texture dimensions /// using transparency-aware analysis. When true, adjusts cell sizes to align /// grid lines with transparent regions for cleaner sprite boundaries. /// public bool snapToTextureDivisor = true; /// /// Gets the config file path for a given texture path. /// /// The path to the source texture. /// The config file path with .spritesheet.json extension. public static string GetConfigPath(string texturePath) { if (string.IsNullOrEmpty(texturePath)) { return string.Empty; } return texturePath + "." + FileExtension; } /// /// Migrates a configuration from an older version to the current version. /// Currently a no-op for version 1, but provides the hook for future migrations. /// /// The configuration to migrate. public static void MigrateConfig(SpriteSheetConfig config) { if (config == null || config.version >= CurrentVersion) { return; } // Migrate v1 -> v2: Add algorithm caching if (config.version < 2) { config.algorithm = (int)AutoDetectionAlgorithm.AutoBest; config.cachedAlgorithmResult = null; config.version = 2; } // Migrate v2 -> v3: Add snapToTextureDivisor persistence if (config.version < 3) { config.snapToTextureDivisor = true; config.version = 3; } config.version = CurrentVersion; } } /// /// Cached result from an auto-detection algorithm run. /// Stored in the config file for cross-session persistence. /// [Serializable] public sealed class CachedAlgorithmResult { /// /// The algorithm that produced this result. /// public int algorithm; /// /// Detected cell width in pixels. /// public int cellWidth; /// /// Detected cell height in pixels. /// public int cellHeight; /// /// Confidence score in the range [0, 1]. /// public float confidence; /// /// Creates a cached result from an algorithm result. /// public static CachedAlgorithmResult FromResult(SpriteSheetAlgorithms.AlgorithmResult result) { return new CachedAlgorithmResult { algorithm = (int)result.Algorithm, cellWidth = result.CellWidth, cellHeight = result.CellHeight, confidence = result.Confidence, }; } /// /// Converts this cached result to an algorithm result. /// public SpriteSheetAlgorithms.AlgorithmResult ToResult() { return new SpriteSheetAlgorithms.AlgorithmResult( cellWidth, cellHeight, confidence, (AutoDetectionAlgorithm)algorithm ); } } #endif }