From 57902430f79fa3ec9f7164665dccc3558e7e2489 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 8 Oct 2023 23:24:16 -0700 Subject: [PATCH] fixed slow load times for refreshing tilemap colliders in the scene view --- Assets/LDtkUnity/CHANGELOG.md | 2 + .../Editor/Builders/LDtkBuilderLayer.cs | 24 +++++-- .../ScriptedImporter/LDtkTilesetImporter.cs | 43 +----------- .../Utility/LDtkTilemapColliderReset.cs | 69 +++++++++++++++++++ .../Utility/LDtkTilemapColliderReset.cs.meta | 3 + Assets/Tools/RefreshTilemaps.cs | 7 +- 6 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs create mode 100644 Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs.meta diff --git a/Assets/LDtkUnity/CHANGELOG.md b/Assets/LDtkUnity/CHANGELOG.md index ecb93cac8..31558b65a 100644 --- a/Assets/LDtkUnity/CHANGELOG.md +++ b/Assets/LDtkUnity/CHANGELOG.md @@ -4,6 +4,8 @@ - To allow the LDtk importer to load Aseprite files, install the [Unity Aseprite Importer](https://docs.unity3d.com/Packages/com.unity.2d.aseprite@1.0/manual/index.html) The Aseprite importer requires Unity 2021.3.15 or above +- Fixed the slow load time to reset tilemap colliders in the scene after reimporting a tileset definition file + - Added a notification in the scene view indicating how many tilemap colliders were reset, and how long it took - Fixed a bug where reordering IntGrid value definitions would use the wrong tile references, and in some cases, cause an exception - Changed the icons for the imported Project/Level/Tileset to match with the icons from LDtk 1.5 diff --git a/Assets/LDtkUnity/Editor/Builders/LDtkBuilderLayer.cs b/Assets/LDtkUnity/Editor/Builders/LDtkBuilderLayer.cs index 6316a2167..26dd6868f 100644 --- a/Assets/LDtkUnity/Editor/Builders/LDtkBuilderLayer.cs +++ b/Assets/LDtkUnity/Editor/Builders/LDtkBuilderLayer.cs @@ -62,17 +62,27 @@ protected void AddTilemapCollider(GameObject tilemapGameObject) CompositeCollider2D composite = tilemapGameObject.AddComponent(); composite.geometryType = Project.GeometryType; + } + + TilemapCollider2D collider = tilemapGameObject.AddComponent(); + ConfigureTilemapCollider(collider); + } + + public static bool ConfigureTilemapCollider(TilemapCollider2D collider) + { + if (!collider.GetComponent()) + { + return false; + } - TilemapCollider2D collider = tilemapGameObject.AddComponent(); + bool usedByComposite = collider.GetComponent(); + #if UNITY_2023_1_OR_NEWER - collider.compositeOperation = Collider2D.CompositeOperation.Merge; + collider.compositeOperation = usedByComposite ? Collider2D.CompositeOperation.Merge : Collider2D.CompositeOperation.None; #else - collider.usedByComposite = true; + collider.usedByComposite = usedByComposite; #endif - return; - } - - tilemapGameObject.AddComponent(); + return true; } } } \ No newline at end of file diff --git a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs index 2f9b1d9c0..01545746c 100644 --- a/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs +++ b/Assets/LDtkUnity/Editor/ScriptedImporter/LDtkTilesetImporter.cs @@ -9,7 +9,6 @@ using UnityEngine.Profiling; using UnityEngine.Tilemaps; using Debug = UnityEngine.Debug; -using Object = UnityEngine.Object; #if LDTK_UNITY_ASEPRITE using UnityEditor.U2D.Aseprite; @@ -32,8 +31,6 @@ namespace LDtkUnity.Editor [ScriptedImporter(LDtkImporterConsts.TILESET_VERSION, LDtkImporterConsts.TILESET_EXT, LDtkImporterConsts.TILESET_ORDER)] internal sealed partial class LDtkTilesetImporter : LDtkJsonImporter { - private static bool _willRefreshTilemapsInScene; - public const string PIXELS_PER_UNIT = nameof(_pixelsPerUnit); [SerializeField] internal int _pixelsPerUnit = -1; @@ -193,8 +190,8 @@ protected override void Import() ImportContext.AddObjectToAsset("tilesetFile", _tilesetFile, LDtkIconUtility.LoadTilesetIcon()); ImportContext.SetMainObject(outputTexture); - - TilemapColliderTileUpdate(); + + LDtkTilemapColliderReset.TilemapColliderTileUpdate(); } private LDtkArtifactAssetsTileset MakeAndCacheArtifacts(TextureGenerationOutput output) @@ -334,41 +331,7 @@ string MakeAssetName() Debug.Assert(_additionalTiles.Count == additionalRects.Count); } - private static void TilemapColliderTileUpdate() - { - //Refresh tilemap colliders in the current scene. - //Tiles would normally not update in the scene view until entering play mode, or reloading the scene, or resetting the component. - //This will immediately update it. - //Using 2023.1+ is much more optimized for this sort of thing. - //This is unfortunately a slow procedure, but there is currently no easy solution found for refreshing tilemap colliders in the scene. - - if (_willRefreshTilemapsInScene) - { - return; - } - _willRefreshTilemapsInScene = true; - - EditorApplication.delayCall += () => - { - Profiler.BeginSample("TilemapColliderTileUpdate"); - _willRefreshTilemapsInScene = false; - -#if UNITY_2023_1_OR_NEWER - TilemapCollider2D[] colliders = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); -#elif UNITY_2020_1_OR_NEWER - TilemapCollider2D[] colliders = Object.FindObjectsOfType(true); -#else - TilemapCollider2D[] colliders = Object.FindObjectsOfType(); -#endif - foreach (var collider in colliders) - { - Unsupported.SmartReset(collider); - PrefabUtility.RevertObjectOverride(collider, InteractionMode.AutomatedAction); - } - - Profiler.EndSample(); - }; - } + private bool PrepareGenerate(TextureImporterPlatformSettings platformSettings, out TextureGenerationOutput output) { diff --git a/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs b/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs new file mode 100644 index 000000000..5297e6977 --- /dev/null +++ b/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs @@ -0,0 +1,69 @@ +using System.Diagnostics; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityEngine.Tilemaps; + +namespace LDtkUnity.Editor +{ + internal static class LDtkTilemapColliderReset + { + private static bool _willRefreshTilemapsInScene; + + public static void TilemapColliderTileUpdate() + { + //Refresh tilemap colliders in the current scene. + //Tiles would normally not update in the scene view until entering play mode, or reloading the scene, or resetting the component. + //This will immediately update it. + //There is currently no easy solution found for refreshing tilemap colliders in the scene, so this is the best solution I could find for now. + //Related forum: https://forum.unity.com/threads/ispritephysicsoutlinedataprovider-is-not-updating-the-tilemapcollider2d-in-the-scene-immediately.1458874/#post-9358610 + + if (_willRefreshTilemapsInScene) + { + return; + } + _willRefreshTilemapsInScene = true; + + EditorApplication.delayCall += () => + { + _willRefreshTilemapsInScene = false; + + Stopwatch watch = Stopwatch.StartNew(); + + //should only try resetting tilemaps that are in an LDtk hierarchy + var levels = LDtkFindInScenes.FindInAllScenes(); + if (levels.IsNullOrEmpty()) + { + watch.Stop(); + return; + } + + var layers = levels.SelectMany(p => p.GetComponentsInChildren()).ToList(); + if (layers.IsNullOrEmpty()) + { + watch.Stop(); + return; + } + + var colliders = layers.SelectMany(p => p.GetComponentsInChildren()).ToList(); + int affected = 0; + foreach (var collider in colliders) + { + Unsupported.SmartReset(collider); + if (LDtkBuilderLayer.ConfigureTilemapCollider(collider)) + { + affected++; + } + } + watch.Stop(); + + SceneView view = SceneView.lastActiveSceneView; + if (view != null && affected > 0) + { + float seconds = watch.ElapsedMilliseconds * 0.001f; + view.ShowNotification(new GUIContent($"Refreshed LDtk scene tilemaps\n({affected} in {seconds:F2}s)"), 2.5f); + } + }; + } + } +} \ No newline at end of file diff --git a/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs.meta b/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs.meta new file mode 100644 index 000000000..eaf517123 --- /dev/null +++ b/Assets/LDtkUnity/Editor/Utility/LDtkTilemapColliderReset.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 56691b4d2348433491074227f4309544 +timeCreated: 1696749985 \ No newline at end of file diff --git a/Assets/Tools/RefreshTilemaps.cs b/Assets/Tools/RefreshTilemaps.cs index 902050dad..72108d655 100644 --- a/Assets/Tools/RefreshTilemaps.cs +++ b/Assets/Tools/RefreshTilemaps.cs @@ -19,12 +19,7 @@ private static void UpdateTilemaps() [MenuItem("LDtkUnity/Refresh Tilemap Colliders", false, 10)] private static void UpdateTilemapColliders() { - TilemapCollider2D[] colliders = Object.FindObjectsByType(FindObjectsSortMode.None); - foreach (TilemapCollider2D collider in colliders) - { - Unsupported.SmartReset(collider); - PrefabUtility.RevertObjectOverride(collider, InteractionMode.AutomatedAction); - } + LDtkTilemapColliderReset.TilemapColliderTileUpdate(); } }