diff --git a/Assets/LDtkUnity/Editor/Builders/LDtkProjectImporterFactory.cs b/Assets/LDtkUnity/Editor/Builders/LDtkBuilderProjectFactory.cs similarity index 84% rename from Assets/LDtkUnity/Editor/Builders/LDtkProjectImporterFactory.cs rename to Assets/LDtkUnity/Editor/Builders/LDtkBuilderProjectFactory.cs index e2926bba5..49e3d6b02 100644 --- a/Assets/LDtkUnity/Editor/Builders/LDtkProjectImporterFactory.cs +++ b/Assets/LDtkUnity/Editor/Builders/LDtkBuilderProjectFactory.cs @@ -2,11 +2,11 @@ namespace LDtkUnity.Editor { - internal sealed class LDtkProjectImporterFactory + internal sealed class LDtkBuilderProjectFactory { private readonly LDtkProjectImporter _importer; - public LDtkProjectImporterFactory(LDtkProjectImporter importer) + public LDtkBuilderProjectFactory(LDtkProjectImporter importer) { _importer = importer; } @@ -17,7 +17,7 @@ public void Import(LdtkJson json) if (projectGameObject == null) { - LDtkDebug.LogError("LDtk: Project GameObject null, not building correctly", _importer.ImportContext); + _importer.Logger.LogError("LDtk: Project GameObject null, not building correctly"); return; } diff --git a/Assets/LDtkUnity/Editor/Builders/LDtkProjectImporterFactory.cs.meta b/Assets/LDtkUnity/Editor/Builders/LDtkBuilderProjectFactory.cs.meta similarity index 100% rename from Assets/LDtkUnity/Editor/Builders/LDtkProjectImporterFactory.cs.meta rename to Assets/LDtkUnity/Editor/Builders/LDtkBuilderProjectFactory.cs.meta diff --git a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkJsonImporter.cs b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkJsonImporter.cs index fe8cc055a..9917ce55d 100644 --- a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkJsonImporter.cs +++ b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkJsonImporter.cs @@ -15,6 +15,8 @@ internal abstract class LDtkJsonImporter : ScriptedImporter public const string REIMPORT_ON_DEPENDENCY_CHANGE = nameof(_reimportOnDependencyChange); [SerializeField] private bool _reimportOnDependencyChange = true; + public LDtkDebugInstance Logger; + public bool ReimportOnDependencyChange => _reimportOnDependencyChange; public AssetImportContext ImportContext { get; private set; } public string AssetName => Path.GetFileNameWithoutExtension(assetPath); @@ -24,6 +26,7 @@ internal abstract class LDtkJsonImporter : ScriptedImporter public sealed override void OnImportAsset(AssetImportContext ctx) { ImportContext = ctx; + Logger = new LDtkDebugInstance(ctx); if (LDtkPrefs.VerboseLogging) { @@ -91,14 +94,14 @@ protected T ReadAssetText() public TJson FromJson() { - return FromJson(assetPath, ImportContext); + return FromJson(assetPath, Logger); } - public static TJson FromJson(string path, AssetImportContext ctx = null) + public static TJson FromJson(string path, LDtkDebugInstance debug = null) { if (!File.Exists(path)) { - LDtkDebug.LogError($"Could not find the json file to deserialize at \"{path}\""); + LDtkDebug.LogError($"Could not find the json file to deserialize at \"{path}\"", debug); return default; } @@ -116,7 +119,7 @@ public static TJson FromJson(string path, AssetImportContext ctx = null) } catch (Exception e) { - LDtkDebug.LogError($"Failure to deserialize json: {e}", ctx); + LDtkDebug.LogError($"Failure to deserialize json: {e}", debug); } Profiler.EndSample(); diff --git a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkLevelImporter.cs b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkLevelImporter.cs index b9e047660..01f0b8dcf 100644 --- a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkLevelImporter.cs +++ b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkLevelImporter.cs @@ -114,7 +114,7 @@ private bool DeserializeAndAssign() if (_projectImporter == null) { string levelName = _levelJson != null ? _levelJson.Identifier : ""; - LDtkDebug.LogError($"Tried to build level {levelName}, but the project importer was not found"); + Logger.LogError($"Tried to build level {levelName}, but the project importer was not found"); return false; } @@ -124,7 +124,7 @@ private bool DeserializeAndAssign() if (_projectJson == null) { - LDtkDebug.LogError("Tried to build level, but the project json data was null"); + Logger.LogError("Tried to build level, but the project json data was null"); return false; } @@ -134,7 +134,7 @@ private bool DeserializeAndAssign() if (_levelFile == null) { - LDtkDebug.LogError("Tried to build level, but the level json ScriptableObject was null"); + Logger.LogError("Tried to build level, but the level json ScriptableObject was null"); return false; } @@ -144,7 +144,7 @@ private bool DeserializeAndAssign() } catch (Exception e) { - LDtkDebug.LogError(e.ToString()); + Logger.LogError(e.ToString()); return false; } diff --git a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkProjectImporter.cs b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkProjectImporter.cs index 1cff7b543..01d99ad20 100644 --- a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkProjectImporter.cs +++ b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkProjectImporter.cs @@ -115,7 +115,7 @@ protected override void Import() Profiler.BeginSample("CheckOutdatedJsonVersion"); string version = ""; LDtkJsonDigger.GetJsonVersion(assetPath, ref version); - if (!CheckOutdatedJsonVersion(version, AssetName, ImportContext)) + if (!CheckOutdatedJsonVersion(version, AssetName, Logger)) { Profiler.EndSample(); BufferEditorCache(); @@ -129,7 +129,7 @@ protected override void Import() if (!TryGetJson(out LdtkJson json)) { - LDtkDebug.LogError("Json deserialization error. Not importing.", ImportContext); + Logger.LogError("Json deserialization error. Not importing."); BufferEditorCache(); return; } @@ -184,7 +184,7 @@ private static void CheckDefaultEditorBehaviour() } } - public static bool CheckOutdatedJsonVersion(string jsonVersion, string assetName, AssetImportContext projectCtx = null) + public static bool CheckOutdatedJsonVersion(string jsonVersion, string assetName, LDtkDebugInstance projectCtx = null) { jsonVersion = Regex.Replace(jsonVersion, "[^0-9.]", ""); if (!Version.TryParse(jsonVersion, out Version version)) @@ -211,7 +211,7 @@ private bool TryGetJson(out LdtkJson json) return true; } - LDtkDebug.LogError("LDtk: Json import error", ImportContext); + Logger.LogError("LDtk: Json import error"); return false; } @@ -242,7 +242,7 @@ private void BufferEditorCache() private void MainBuild(LdtkJson json) { - LDtkProjectImporterFactory factory = new LDtkProjectImporterFactory(this); + LDtkBuilderProjectFactory factory = new LDtkBuilderProjectFactory(this); factory.Import(json); } @@ -281,7 +281,7 @@ private void CreateBackgroundArtifacts(LdtkJson json) { if (input == null) { - LDtkDebug.LogError("LDtk: Tried getting an asset from the build data but the array was null. Is the project asset properly saved?", ImportContext); + Logger.LogError("LDtk: Tried getting an asset from the build data but the array was null. Is the project asset properly saved?"); return default; } @@ -289,7 +289,7 @@ private void CreateBackgroundArtifacts(LdtkJson json) { if (ReferenceEquals(asset, null)) { - LDtkDebug.LogError($"LDtk: A field in the build data is null.", ImportContext); + Logger.LogError($"LDtk: A field in the build data is null."); continue; } @@ -329,14 +329,12 @@ private LDtkArtifactAssetsTileset LoadTilesetArtifacts(TilesetDefinition def) LDtkTilesetImporter importer = LoadAndCacheTilesetImporter(def); if (importer == null) { - LDtkDebug.LogError($"Tried loading the tileset file, but didn't exist? At \"{assetPath}\"", ImportContext); return null; } LDtkArtifactAssetsTileset artifacts = importer.LoadArtifacts(ImportContext); if (artifacts == null) { - LDtkDebug.LogError($"Loading artifacts didn't work for getting tileset sprite artifacts. Was the tileset file properly imported? At \"{assetPath}\"", ImportContext); return null; } @@ -347,53 +345,59 @@ public Sprite GetBackgroundArtifact(Level level) { if (_backgroundArtifacts == null) { - LDtkDebug.LogError("Project importer's artifact assets was null, this needs to be cached", ImportContext); + Logger.LogError("Project importer's artifact assets was null, this needs to be cached"); return null; } string assetName = level.Identifier; Sprite asset = _backgroundArtifacts.GetBackgroundSlow(assetName); if (asset != null) - { + { return asset; } - LDtkDebug.LogError($"Tried retrieving a background from the importer's artifacts, but was null: \"{assetName}\"", ImportContext); + Logger.LogError($"Tried retrieving a background from the importer's artifacts, but was null: \"{assetName}\""); return asset; } public LDtkTilesetImporter LoadAndCacheTilesetImporter(TilesetDefinition def) { - if (!_importersForDefs.TryGetValue(def, out LDtkTilesetImporter importer)) + if (_importersForDefs.TryGetValue(def, out LDtkTilesetImporter importer)) { - string path = TilesetImporterPath(def); - importer = (LDtkTilesetImporter)GetAtPath(path); - _importersForDefs.Add(def, importer); - Debug.Log($"Cache Tileset importer {path}"); + return importer; } + + string path = TilesetImporterPath(assetPath, def.Identifier); + if (!File.Exists(path)) + { + Logger.LogError($"Failed to find the required tileset file at \"{path}\". Ensure that LDtk exported a tileset file through a custom command. If the command wasn't configured yet, check the project inspector for more info."); + return null; + } + + importer = (LDtkTilesetImporter)GetAtPath(path); if (importer == null) { - string path = TilesetImporterPath(def); - _importersForDefs[def] = (LDtkTilesetImporter)GetAtPath(path); - Debug.Log($"Cache Tileset importer {path}"); + Logger.LogError($"Failed to find the required tileset file importer at \"{path}\", but the file exists. The tileset file may have failed to import?"); + return null; } - - return _importersForDefs[def]; + + _importersForDefs.Add(def, importer); + return importer; } - public string TilesetImporterPath(TilesetDefinition def) + public static string TilesetImporterPath(string projectPath, string tilesetDefIdentifier) { - string directoryName = Path.GetDirectoryName(assetPath); - string projectName = Path.GetFileNameWithoutExtension(assetPath); + string directoryName = Path.GetDirectoryName(projectPath); + string projectName = Path.GetFileNameWithoutExtension(projectPath); if (directoryName == null) { - LDtkDebug.LogError($"Issue formulating a tileset definition path; Path was invalid for: {assetPath}", ImportContext); + LDtkDebug.LogError($"Issue formulating a tileset definition path; Path was invalid for: \"{projectPath}\""); return null; } - return Path.Combine(directoryName, projectName, def.Identifier) + '.' + LDtkImporterConsts.TILESET_EXT; + return Path.Combine(directoryName, projectName, tilesetDefIdentifier) + '.' + LDtkImporterConsts.TILESET_EXT; } private void OnResetPPU() @@ -438,7 +442,7 @@ public void TryCacheArtifactsAsset() _backgroundArtifacts = AssetDatabase.LoadAssetAtPath(assetPath); if (_backgroundArtifacts == null) { - LDtkDebug.LogError($"Artifacts was null during the import, this should never happen. Does the sub asset not exist for \"{assetPath}\"?", ImportContext); + Logger.LogError($"Artifacts was null during the import, this should never happen. Does the sub asset not exist for \"{assetPath}\"?"); } } } diff --git a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs index f54141298..2834a163a 100644 --- a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs +++ b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs @@ -117,23 +117,23 @@ protected override void Import() Texture2D outputTexture = output.texture; if (output.sprites.IsNullOrEmpty() && outputTexture == null) { - LDtkDebug.LogWarning("No Sprites or Texture are generated. Possibly because all assets in file are hidden or failed to generate texture.", ImportContext, this); + Logger.LogWarning("No Sprites or Texture are generated. Possibly because all assets in file are hidden or failed to generate texture."); return; } if (!string.IsNullOrEmpty(output.importInspectorWarnings)) { - LDtkDebug.LogWarning(output.importInspectorWarnings, ImportContext); + Logger.LogWarning(output.importInspectorWarnings); } if (output.importWarnings != null) { foreach (var warning in output.importWarnings) { - LDtkDebug.LogWarning(warning, ImportContext); + Logger.LogWarning(warning); } } if (output.thumbNail == null) { - LDtkDebug.LogWarning("Thumbnail generation fail", ImportContext); + Logger.LogWarning("Thumbnail generation fail"); } outputTexture.name = AssetName; @@ -337,7 +337,7 @@ private bool DeserializeAndAssign() } catch (Exception e) { - LDtkDebug.LogError(e.ToString(), ImportContext); + Logger.LogError(e.ToString()); return false; } @@ -347,7 +347,7 @@ private bool DeserializeAndAssign() if (_srcTextureImporter == null) { - LDtkDebug.LogError($"Tried to build tileset {AssetName}, but the texture importer was not found. Is this tileset asset in a folder relative to the LDtk project file? Ensure that it's relativity is maintained if the project was moved also.", ImportContext); + Logger.LogError($"Tried to build tileset {AssetName}, but the texture importer was not found. Is this tileset asset in a folder relative to the LDtk project file? Ensure that it's relativity is maintained if the project was moved also."); return false; } @@ -357,7 +357,7 @@ private bool DeserializeAndAssign() if (_tilesetFile == null) { - LDtkDebug.LogError("Tried to build tileset, but the tileset json ScriptableObject was null", ImportContext); + Logger.LogError("Tried to build tileset, but the tileset json ScriptableObject was null"); return false; } @@ -503,12 +503,14 @@ public LDtkArtifactAssetsTileset LoadArtifacts(AssetImportContext projectCtx) { _cachedArtifacts = AssetDatabase.LoadAssetAtPath(assetPath); } + //It's possible that the artifact assets don't exist, either because the texture importer failed to import, or the artifact assets weren't produced due to being an aseprite file or otherwise if (_cachedArtifacts == null) { - LDtkDebug.LogError($"Cached artifacts didnt load! For \"{assetPath}\"", projectCtx); - + Logger.LogError($"Loading artifacts didn't work for getting tileset sprite artifacts. Was the tileset file properly imported? At \"{assetPath}\""); + return null; } + return _cachedArtifacts; } diff --git a/Assets/LDtkUnity/Runtime/Tools/LDtkDebug.cs b/Assets/LDtkUnity/Runtime/Tools/LDtkDebug.cs index 8e7733c60..ab2ea8eb5 100644 --- a/Assets/LDtkUnity/Runtime/Tools/LDtkDebug.cs +++ b/Assets/LDtkUnity/Runtime/Tools/LDtkDebug.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using UnityEditor; using UnityEngine; #if UNITY_EDITOR @@ -12,11 +13,13 @@ namespace LDtkUnity { //because logging the same message hundreds of times is very slow, we'll limit the max of the same log up to a certain amount + internal static class LDtkDebug { private const int MAX_LOGS = 50; private static readonly Dictionary Messages = new Dictionary(); + private static bool _dueToResetThisFrame; public static void Log(string msg, Object context = null) { @@ -45,6 +48,17 @@ public static void Assert(bool condition, string msg = "Assertion failed", Objec private static bool ShouldBlock(string msg) { + if (!_dueToResetThisFrame) + { + EditorApplication.delayCall += Flush; + void Flush() + { + Messages.Clear(); + _dueToResetThisFrame = false; + } + _dueToResetThisFrame = true; + } + if (!Messages.ContainsKey(msg)) { Messages.Add(msg, 1); @@ -58,8 +72,9 @@ private static bool ShouldBlock(string msg) Messages[msg]++; return false; } - - private static string Format(string msg) + + + public static string Format(string msg) { #if UNITY_EDITOR return $"LDtk: {msg}"; @@ -73,31 +88,24 @@ public static string GetStringColor() { return UnityEditor.EditorGUIUtility.isProSkin ? "#FFCC00" : "#997A00"; } - - public static void LogError(string msg, AssetImportContext ctx, Object obj = null) - { - if (ShouldBlock(msg)) return; - if (ctx != null) - { - ctx.LogImportError(msg + '\n' + StackTraceUtility.ExtractStackTrace(), obj); - } - else + public static void LogError(string msg, LDtkDebugInstance debug, Object context = null) + { + if (debug != null) { - Debug.LogError(Format(msg), obj); + debug.LogError(msg, context); + return; } + LogError(msg, context); } - - public static void LogWarning(string msg, AssetImportContext ctx, Object obj = null) + public static void LogWarning(string msg, LDtkDebugInstance debug, Object context = null) { - if (ShouldBlock(msg)) return; - - if (ctx != null) + if (debug != null) { - ctx.LogImportWarning(msg + '\n' + StackTraceUtility.ExtractStackTrace(), obj); + debug.LogWarning(msg, context); return; } - Debug.LogWarning(Format(msg), obj); + LogWarning(msg, context); } #endif } diff --git a/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs b/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs new file mode 100644 index 000000000..e13541589 --- /dev/null +++ b/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs @@ -0,0 +1,51 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using UnityEngine; + +#if UNITY_2020_2_OR_NEWER +using UnityEditor.AssetImporters; +#else +using UnityEditor.Experimental.AssetImporters; +#endif + +namespace LDtkUnity +{ + internal sealed class LDtkDebugInstance + { + private readonly HashSet _importMessages = new HashSet(); + private readonly AssetImportContext _ctx; + + public LDtkDebugInstance(AssetImportContext ctx) + { + _ctx = ctx; + } + + public void LogError(string msg, Object obj = null) + { + if (!ShouldBlockImport(msg)) + { + _ctx.LogImportError(LDtkDebug.Format(msg) + '\n' + StackTraceUtility.ExtractStackTrace(), obj); + } + } + + public void LogWarning(string msg, Object obj = null) + { + if (!ShouldBlockImport(msg)) + { + _ctx.LogImportWarning(LDtkDebug.Format(msg) + '\n' + StackTraceUtility.ExtractStackTrace(), obj); + } + } + + private bool ShouldBlockImport(string msg) + { + if (_importMessages.Contains(msg)) + { + return true; + } + + _importMessages.Add(msg); + return false; + } + } +} +#endif diff --git a/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs.meta b/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs.meta new file mode 100644 index 000000000..cf48a5da4 --- /dev/null +++ b/Assets/LDtkUnity/Runtime/Tools/LDtkDebugInstance.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 46a091b5a2fc41568816f039b6b39129 +timeCreated: 1692173475 \ No newline at end of file