From b3e8821966d8250cc324ea7f11edf63131a27aaa Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 5 Oct 2023 20:51:50 +0200 Subject: [PATCH 1/6] [godot] Fix const assignments in SpineAtlasResource::copy_from() --- spine-godot/spine_godot/SpineAtlasResource.cpp | 3 +-- spine-godot/spine_godot/SpineAtlasResource.h | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index 3dc42fd90..e588ac7af 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -239,9 +239,8 @@ Error SpineAtlasResource::copy_from(const Ref &p_resource) { const Ref &spineAtlas = static_cast &>(p_resource); this->clear(); this->atlas = spineAtlas->atlas; - spineAtlas->atlas = nullptr; this->texture_loader = spineAtlas->texture_loader; - spineAtlas->texture_loader = nullptr; + spineAtlas->clear_native_data(); this->source_path = spineAtlas->source_path; this->atlas_data = spineAtlas->atlas_data; diff --git a/spine-godot/spine_godot/SpineAtlasResource.h b/spine-godot/spine_godot/SpineAtlasResource.h index be504ae2a..5105d9606 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.h +++ b/spine-godot/spine_godot/SpineAtlasResource.h @@ -76,6 +76,11 @@ public: Array get_textures(); Array get_normal_maps(); + + void clear_native_data() { + this->atlas = nullptr; + this->texture_loader = nullptr; + } }; class SpineAtlasResourceFormatLoader : public ResourceFormatLoader { From 5f6b637d53db7ad4020fa2c79450bc2e0583f599 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 6 Oct 2023 10:50:15 +0200 Subject: [PATCH 2/6] [godot] Make SpineAtlasResource::clear_native_data const. --- spine-godot/spine_godot/SpineAtlasResource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-godot/spine_godot/SpineAtlasResource.h b/spine-godot/spine_godot/SpineAtlasResource.h index 5105d9606..af27d6cd9 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.h +++ b/spine-godot/spine_godot/SpineAtlasResource.h @@ -77,7 +77,7 @@ public: Array get_normal_maps(); - void clear_native_data() { + const void clear_native_data() { this->atlas = nullptr; this->texture_loader = nullptr; } From 66f2bfeb610791e5cfa6f9156fd3ed4d589fcac8 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 6 Oct 2023 10:53:09 +0200 Subject: [PATCH 3/6] [godot] Update 3.5 editor build to 3.5.3-stable --- .github/workflows/spine-godot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spine-godot.yml b/.github/workflows/spine-godot.yml index fa4cab519..cd3d9af80 100644 --- a/.github/workflows/spine-godot.yml +++ b/.github/workflows/spine-godot.yml @@ -12,8 +12,8 @@ env: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_EC2_METADATA_DISABLED: true EM_VERSION: 3.1.14 - GODOT_TAG: 3.5.2-stable - GODOT_VERSION: 3.5.2.stable + GODOT_TAG: 3.5.3-stable + GODOT_VERSION: 3.5.3.stable jobs: godot-editor-windows: From 97fb551ceee266c0fcf818b12b8949b9c390752d Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 6 Oct 2023 10:54:05 +0200 Subject: [PATCH 4/6] [godot] Update 4.1 editor build to 4.1.2-stable --- .github/workflows/spine-godot-v4-all.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spine-godot-v4-all.yml b/.github/workflows/spine-godot-v4-all.yml index 7920d48b2..bb6a41236 100644 --- a/.github/workflows/spine-godot-v4-all.yml +++ b/.github/workflows/spine-godot-v4-all.yml @@ -15,8 +15,8 @@ jobs: version: [ {"tag": "4.0.4-stable", "version": "4.0.4.stable", "mono": false}, - {"tag": "4.1.1-stable", "version": "4.1.1.stable", "mono": false}, - {"tag": "4.1.1-stable", "version": "4.1.1.stable", "mono": true}, + {"tag": "4.1.2-stable", "version": "4.1.2.stable", "mono": false}, + {"tag": "4.1.2-stable", "version": "4.1.2.stable", "mono": true}, ] uses: ./.github/workflows/spine-godot-v4.yml with: From f5caeacf0ce5ffc86a89d115a312a2185cfefd40 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 6 Oct 2023 11:15:21 +0200 Subject: [PATCH 5/6] [godot] Fix compilation errors with 3.5.3, fix const correctness. --- spine-godot/spine_godot/SpineAtlasResource.cpp | 2 ++ spine-godot/spine_godot/SpineAtlasResource.h | 8 +++++--- spine-godot/spine_godot/SpineSkeletonFileResource.cpp | 6 +++++- spine-godot/spine_godot/SpineSkeletonFileResource.h | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index e588ac7af..dbe3b747a 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -232,6 +232,7 @@ Error SpineAtlasResource::save_to_file(const String &path) { return OK; } +#if VERSION_MAJOR > 3 Error SpineAtlasResource::copy_from(const Ref &p_resource) { auto error = Resource::copy_from(p_resource); if (error != OK) return error; @@ -251,6 +252,7 @@ Error SpineAtlasResource::copy_from(const Ref &p_resource) { return OK; } +#endif #if VERSION_MAJOR > 3 RES SpineAtlasResourceFormatLoader::load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) { diff --git a/spine-godot/spine_godot/SpineAtlasResource.h b/spine-godot/spine_godot/SpineAtlasResource.h index af27d6cd9..55807a58e 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.h +++ b/spine-godot/spine_godot/SpineAtlasResource.h @@ -45,8 +45,8 @@ class SpineAtlasResource : public Resource { protected: static void _bind_methods(); - spine::Atlas *atlas; - GodotSpineTextureLoader *texture_loader; + mutable spine::Atlas *atlas; + mutable GodotSpineTextureLoader *texture_loader; String source_path; String atlas_data; @@ -69,7 +69,9 @@ public: Error save_to_file(const String &path);// .spatlas +#if VERSION_MAJOR > 3 virtual Error copy_from(const Ref &p_resource); +#endif String get_source_path(); @@ -77,7 +79,7 @@ public: Array get_normal_maps(); - const void clear_native_data() { + void clear_native_data() const { this->atlas = nullptr; this->texture_loader = nullptr; } diff --git a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp index 0929ba5cf..7880d2a25 100644 --- a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp @@ -28,11 +28,13 @@ *****************************************************************************/ #include "SpineSkeletonFileResource.h" +#if VERSION_MAJOR > 3 #include "core/error/error_list.h" #include "core/error/error_macros.h" -#if VERSION_MAJOR > 3 #include "core/io/file_access.h" #else +#include "core/error_list.h" +#include "core/error_macros.h" #include "core/os/file_access.h" #endif #include @@ -160,6 +162,7 @@ Error SpineSkeletonFileResource::save_to_file(const String &path) { return OK; } +#if VERSION_MAJOR > 3 Error SpineSkeletonFileResource::copy_from(const Ref &p_resource) { auto error = Resource::copy_from(p_resource); if (error != OK) return error; @@ -169,6 +172,7 @@ Error SpineSkeletonFileResource::copy_from(const Ref &p_resource) { emit_signal(SNAME("skeleton_file_changed")); return OK; } +#endif #if VERSION_MAJOR > 3 RES SpineSkeletonFileResourceFormatLoader::load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) { diff --git a/spine-godot/spine_godot/SpineSkeletonFileResource.h b/spine-godot/spine_godot/SpineSkeletonFileResource.h index c3b35569c..94924d3f5 100644 --- a/spine-godot/spine_godot/SpineSkeletonFileResource.h +++ b/spine-godot/spine_godot/SpineSkeletonFileResource.h @@ -53,7 +53,9 @@ public: Error save_to_file(const String &path); +#if VERSION_MAJOR > 3 virtual Error copy_from(const Ref &p_resource); +#endif }; class SpineSkeletonFileResourceFormatLoader : public ResourceFormatLoader { From 8bc1201b8306356b49808bd319a91cbbe44525e5 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Fri, 6 Oct 2023 18:32:09 +0200 Subject: [PATCH 6/6] [unity] On-demand loading of Atlas Textures now supports SkeletonGraphic. Added method `RequestLoadTexture` and TextureRequested delegate to OnDemandTextureLoader. Fixed missing loader asset name suffix. See #1890. --- .../spine-unity/Asset Types/AtlasAssetBase.cs | 5 ++ .../Asset Types/OnDemandTextureLoader.cs | 32 +++++++++++ .../spine-unity/Components/SkeletonGraphic.cs | 55 ++++++++++++++++-- spine-unity/Assets/Spine/package.json | 2 +- .../AddressablesTextureLoaderInspector.cs | 3 +- .../Runtime/AddressablesTextureLoader.cs | 8 ++- .../package.json | 2 +- .../GenericOnDemandTextureLoaderInspector.cs | 22 ++++++-- .../Runtime/GenericOnDemandTextureLoader.cs | 56 +++++++++++++++---- .../package.json | 2 +- 10 files changed, 161 insertions(+), 26 deletions(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs index 59b5bf5b6..4190ef2b1 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAssetBase.cs @@ -71,6 +71,11 @@ namespace Spine.Unity { onDemandTextureLoader.RequestLoadMaterialTextures(material, ref overrideMaterial); } + public virtual void RequireTextureLoaded (Texture placeholderTexture, ref Texture replacementTexture, System.Action onTextureLoaded) { + if (onDemandTextureLoader) + onDemandTextureLoader.RequestLoadTexture(placeholderTexture, ref replacementTexture, onTextureLoaded); + } + [SerializeField] protected LoadingMode textureLoadingMode = LoadingMode.Normal; [SerializeField] protected OnDemandTextureLoader onDemandTextureLoader = null; #endif diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/OnDemandTextureLoader.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/OnDemandTextureLoader.cs index 16de1b725..a7b5c4613 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/OnDemandTextureLoader.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/OnDemandTextureLoader.cs @@ -51,6 +51,27 @@ namespace Spine.Unity { /// A newly created list of materials which has a placeholder texture assigned. /// True, if any placeholder texture is assigned at a Material of the associated AtlasAssetBase. public abstract bool HasPlaceholderTexturesAssigned (out List placeholderMaterials); + + /// + /// Returns whether any main texture is null at a Material of the associated AtlasAssetBase. + /// + /// A newly created list of materials which has a null main texture assigned. + /// True, if any null main texture is assigned at a Material of the associated AtlasAssetBase. + public virtual bool HasNullMainTexturesAssigned (out List nullTextureMaterials) { + nullTextureMaterials = null; + if (!atlasAsset) return false; + + bool anyNullTexture = false; + foreach (Material material in atlasAsset.Materials) { + if (material.mainTexture == null) { + anyNullTexture = true; + if (nullTextureMaterials == null) nullTextureMaterials = new List(); + nullTextureMaterials.Add(material); + } + } + return anyNullTexture; + } + /// /// Assigns previously setup target textures at each Material where placeholder textures are setup. /// True on success, false if the target texture could not be assigned at any of the @@ -60,13 +81,20 @@ namespace Spine.Unity { public abstract void EndCustomTextureLoading (); public abstract bool HasPlaceholderAssigned (Material material); public abstract void RequestLoadMaterialTextures (Material material, ref Material overrideMaterial); + public abstract void RequestLoadTexture (Texture placeholderTexture, ref Texture replacementTexture, + System.Action onTextureLoaded = null); public abstract void Clear (bool clearAtlasAsset = false); #region Event delegates public delegate void TextureLoadDelegate (OnDemandTextureLoader loader, Material material, int textureIndex); + protected event TextureLoadDelegate onTextureRequested; protected event TextureLoadDelegate onTextureLoaded; protected event TextureLoadDelegate onTextureUnloaded; + public event TextureLoadDelegate TextureRequested { + add { onTextureRequested += value; } + remove { onTextureRequested -= value; } + } public event TextureLoadDelegate TextureLoaded { add { onTextureLoaded += value; } remove { onTextureLoaded -= value; } @@ -76,6 +104,10 @@ namespace Spine.Unity { remove { onTextureUnloaded -= value; } } + protected void OnTextureRequested (Material material, int textureIndex) { + if (onTextureRequested != null) + onTextureRequested(this, material, textureIndex); + } protected void OnTextureLoaded (Material material, int textureIndex) { if (onTextureLoaded != null) onTextureLoaded(this, material, textureIndex); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index 92871e4c3..ff963b8c3 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -35,6 +35,8 @@ #define HAS_CULL_TRANSPARENT_MESH #endif +#define SPINE_OPTIONAL_ON_DEMAND_LOADING + using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; @@ -821,14 +823,22 @@ namespace Spine.Unity { else canvasRenderer.SetMesh(null); + bool assignTexture = false; if (currentInstructions.submeshInstructions.Count > 0) { Material material = currentInstructions.submeshInstructions.Items[0].material; if (material != null && baseTexture != material.mainTexture) { baseTexture = material.mainTexture; if (overrideTexture == null && assignAtCanvasRenderer) - canvasRenderer.SetTexture(this.mainTexture); + assignTexture = true; } } + +#if SPINE_OPTIONAL_ON_DEMAND_LOADING + if (Application.isPlaying) + HandleOnDemandLoading(); +#endif + if (assignTexture) + canvasRenderer.SetTexture(this.mainTexture); } protected void UpdateMaterialsMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) { @@ -899,7 +909,6 @@ namespace Spine.Unity { bool pmaVertexColors = meshGenerator.settings.pmaVertexColors; Material[] usedMaterialItems = usedMaterials.Items; Texture[] usedTextureItems = usedTextures.Items; - bool assignAtCanvasRenderer = (assignMeshOverrideSingle == null || !disableMeshAssignmentOnOverride); for (int i = 0; i < submeshCount; i++) { SubmeshInstruction submeshInstructionItem = currentInstructions.submeshInstructions.Items[i]; meshGenerator.Begin(); @@ -932,13 +941,51 @@ namespace Spine.Unity { #endif } canvasRenderer.materialCount = 1; - if (assignAtCanvasRenderer) - canvasRenderer.SetMaterial(usedMaterialItems[i], usedTextureItems[i]); } + +#if SPINE_OPTIONAL_ON_DEMAND_LOADING + if (Application.isPlaying) + HandleOnDemandLoading(); +#endif + bool assignAtCanvasRenderer = (assignMeshOverrideSingle == null || !disableMeshAssignmentOnOverride); + if (assignAtCanvasRenderer) { + for (int i = 0; i < submeshCount; i++) { + CanvasRenderer canvasRenderer = canvasRenderers[i]; + canvasRenderer.SetMaterial(usedMaterialItems[i], usedTextureItems[i]); + } + } + if (assignMeshOverrideMultiple != null) assignMeshOverrideMultiple(submeshCount, meshesItems, usedMaterialItems, usedTextureItems); } +#if SPINE_OPTIONAL_ON_DEMAND_LOADING + void HandleOnDemandLoading () { + foreach (AtlasAssetBase atlasAsset in skeletonDataAsset.atlasAssets) { + if (atlasAsset.TextureLoadingMode != AtlasAssetBase.LoadingMode.Normal) { + atlasAsset.BeginCustomTextureLoading(); + + if (!this.allowMultipleCanvasRenderers) { + Texture loadedTexture = null; + atlasAsset.RequireTextureLoaded(this.mainTexture, ref loadedTexture, null); + if (loadedTexture) + this.baseTexture = loadedTexture; + } + else { + Texture[] textureItems = usedTextures.Items; + for (int i = 0, count = usedTextures.Count; i < count; ++i) { + Texture loadedTexture = null; + atlasAsset.RequireTextureLoaded(textureItems[i], ref loadedTexture, null); + if (loadedTexture) + usedTextures.Items[i] = loadedTexture; + } + } + atlasAsset.EndCustomTextureLoading(); + } + } + } +#endif + protected void EnsureCanvasRendererCount (int targetCount) { #if UNITY_EDITOR RemoveNullCanvasRenderers(); diff --git a/spine-unity/Assets/Spine/package.json b/spine-unity/Assets/Spine/package.json index 039bc6651..a21deed83 100644 --- a/spine-unity/Assets/Spine/package.json +++ b/spine-unity/Assets/Spine/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.spine-unity", "displayName": "spine-unity Runtime", "description": "This plugin provides the spine-unity runtime core.", - "version": "4.1.28", + "version": "4.1.29", "unity": "2018.3", "author": { "name": "Esoteric Software", diff --git a/spine-unity/Modules/com.esotericsoftware.spine.addressables/Editor/AddressablesTextureLoaderInspector.cs b/spine-unity/Modules/com.esotericsoftware.spine.addressables/Editor/AddressablesTextureLoaderInspector.cs index dcb3bf2a4..f0af3df67 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.addressables/Editor/AddressablesTextureLoaderInspector.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.addressables/Editor/AddressablesTextureLoaderInspector.cs @@ -47,9 +47,10 @@ namespace Spine.Unity.Editor { [CustomEditor(typeof(AddressablesTextureLoader)), CanEditMultipleObjects] public class AddressablesTextureLoaderInspector : GenericTextureLoaderInspector { - public string LoaderSuffix { get { return "_Addressable"; } } public class AddressablesMethodImplementations : StaticMethodImplementations { + public override string LoaderSuffix { get { return "_Addressable"; } } + public override GenericTextureLoader GetOrCreateLoader (string loaderPath) { AddressablesTextureLoader loader = AssetDatabase.LoadAssetAtPath(loaderPath); if (loader == null) { diff --git a/spine-unity/Modules/com.esotericsoftware.spine.addressables/Runtime/AddressablesTextureLoader.cs b/spine-unity/Modules/com.esotericsoftware.spine.addressables/Runtime/AddressablesTextureLoader.cs index be137bb4b..3411087f2 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.addressables/Runtime/AddressablesTextureLoader.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.addressables/Runtime/AddressablesTextureLoader.cs @@ -76,13 +76,17 @@ namespace Spine.Unity { [System.Serializable] public class AddressablesTextureLoader : GenericOnDemandTextureLoader { public override void CreateTextureRequest (AddressableTextureReference targetReference, - MaterialOnDemandData materialData, int textureIndex, Material materialToUpdate) { + MaterialOnDemandData materialData, int textureIndex, Material materialToUpdate, + System.Action onTextureLoaded) { + OnTextureRequested(materialToUpdate, textureIndex); materialData.textureRequests[textureIndex].handle = targetReference.assetReference.LoadAssetAsync(); materialData.textureRequests[textureIndex].handle.Completed += (obj) => { if (obj.Status == AsyncOperationStatus.Succeeded) { - materialToUpdate.mainTexture = (Texture)targetReference.assetReference.Asset; + Texture loadedTexture = (Texture)targetReference.assetReference.Asset; + materialToUpdate.mainTexture = loadedTexture; OnTextureLoaded(materialToUpdate, textureIndex); + if (onTextureLoaded != null) onTextureLoaded(loadedTexture); } }; } diff --git a/spine-unity/Modules/com.esotericsoftware.spine.addressables/package.json b/spine-unity/Modules/com.esotericsoftware.spine.addressables/package.json index 56662e150..f2ae6d3e0 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.addressables/package.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.addressables/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.addressables", "displayName": "Spine Addressables Extensions [Experimental]", "description": "This experimental plugin provides integration of Addressables on-demand texture loading for the spine-unity runtime.\nPlease be sure to test this package first and create backups of your project before using.\n\nUsage: First declare your target Material textures as addressable. Then select the SpineAtlasAsset, right-click the SpineAtlasAsset Inspector heading and select 'Add Addressables Loader'. This generates an 'AddressableTextureLoader' asset providing configuration parameters and sets up low-resolution placeholder textures which are automatically assigned in a pre-build step when building your game executable.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime (via the spine-unity unitypackage), version 4.1.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.1.0-preview.1", + "version": "4.1.0-preview.2", "unity": "2018.3", "author": { "name": "Esoteric Software", diff --git a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Editor/GenericOnDemandTextureLoaderInspector.cs b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Editor/GenericOnDemandTextureLoaderInspector.cs index 9744617fc..786e1b8b7 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Editor/GenericOnDemandTextureLoaderInspector.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Editor/GenericOnDemandTextureLoaderInspector.cs @@ -37,6 +37,7 @@ using System; using System.Collections.Generic; +using System.Linq; using UnityEditor; using UnityEngine; @@ -92,7 +93,7 @@ namespace Spine.Unity.Editor { /// When set to e.g. "_Addressable", the loader asset created for /// the "Skeleton_Atlas" asset is named "Skeleton_Addressable". /// - public string LoaderSuffix { get; } + public virtual string LoaderSuffix { get { return "_Loader"; } } public abstract bool SetupOnDemandLoadingReference ( ref TargetReference targetTextureReference, Texture targetTexture); @@ -237,7 +238,7 @@ namespace Spine.Unity.Editor { #if NEWPLAYMODECALLBACKS static void OnPlaymodeChanged (PlayModeStateChange mode) { - bool assignTargetTextures = mode == PlayModeStateChange.ExitingPlayMode; + bool assignTargetTextures = mode == PlayModeStateChange.EnteredEditMode; #else static void OnPlaymodeChanged () { bool assignTargetTextures = !Application.isPlaying; @@ -259,14 +260,23 @@ namespace Spine.Unity.Editor { public static void AssignTargetTexturesAtLoader (OnDemandTextureLoader loader) { List placeholderMaterials; + List nullTextureMaterials; bool anyPlaceholdersAssigned = loader.HasPlaceholderTexturesAssigned(out placeholderMaterials); - if (anyPlaceholdersAssigned) { - Debug.Log("OnDemandTextureLoader detected placeholders assigned at one or more materials. Resetting to target textures.", loader); + bool anyMaterialNull = loader.HasNullMainTexturesAssigned(out nullTextureMaterials); + if (anyPlaceholdersAssigned || anyMaterialNull) { + Debug.Log("OnDemandTextureLoader detected placeholders assigned or null main textures at one or more materials. Resetting to target textures.", loader); AssetDatabase.StartAssetEditing(); IEnumerable modifiedMaterials; loader.AssignTargetTextures(out modifiedMaterials); - foreach (Material placeholderMaterial in placeholderMaterials) { - EditorUtility.SetDirty(placeholderMaterial); + if (placeholderMaterials != null) { + foreach (Material placeholderMaterial in placeholderMaterials) { + EditorUtility.SetDirty(placeholderMaterial); + } + } + if (nullTextureMaterials != null) { + foreach (Material nullTextureMaterial in nullTextureMaterials) { + EditorUtility.SetDirty(nullTextureMaterial); + } } AssetDatabase.StopAssetEditing(); AssetDatabase.SaveAssets(); diff --git a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Runtime/GenericOnDemandTextureLoader.cs b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Runtime/GenericOnDemandTextureLoader.cs index 47a02f031..5025701b5 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Runtime/GenericOnDemandTextureLoader.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/Runtime/GenericOnDemandTextureLoader.cs @@ -164,6 +164,7 @@ namespace Spine.Unity { if (placeholderMaterials == null) placeholderMaterials = new List(); placeholderMaterials.Add(material); } + materialIndex++; } return anyPlaceholderAssigned; } @@ -180,8 +181,7 @@ namespace Spine.Unity { atlasAsset, i + 1, targetMaterial), this); return false; } - Material ignoredArgument = null; - RequestLoadMaterialTextures(targetMaterial, ref ignoredArgument); + AssignTargetTextures(targetMaterial, i); ++i; } modifiedMaterials = atlasAsset.Materials; @@ -223,7 +223,7 @@ namespace Spine.Unity { int foundMaterialIndex = Array.FindIndex(placeholderMap, entry => entry.textures[textureIndex].placeholderTexture == currentTexture); if (foundMaterialIndex >= 0) - RequestLoadTexture(material, foundMaterialIndex, textureIndex); + RequestLoadTexture(material, foundMaterialIndex, textureIndex, null); int loadedMaterialIndex = Array.FindIndex(loadedDataAtMaterial, entry => entry.textureRequests[textureIndex].WasRequested && @@ -232,33 +232,69 @@ namespace Spine.Unity { loadedDataAtMaterial[loadedMaterialIndex].lastFrameRequested = Time.frameCount; } - protected virtual void RequestLoadTexture (Material material, int materialIndex, int textureIndex) { + public override void RequestLoadTexture (Texture placeholderTexture, ref Texture replacementTexture, + System.Action onTextureLoaded = null) { + + if (placeholderTexture == null) return; + + Texture currentTexture = placeholderTexture; + int textureIndex = 0; // Todo: currently only main texture is supported. + + int foundMaterialIndex = Array.FindIndex(placeholderMap, entry => entry.textures[textureIndex].placeholderTexture == currentTexture); + if (foundMaterialIndex >= 0) { + Material material = atlasAsset.Materials.ElementAt(foundMaterialIndex); + Texture loadedTexture = RequestLoadTexture(material, foundMaterialIndex, textureIndex, onTextureLoaded); + if (loadedTexture != null) + replacementTexture = loadedTexture; + } + + int loadedMaterialIndex = Array.FindIndex(loadedDataAtMaterial, entry => + entry.textureRequests[textureIndex].WasRequested && + entry.textureRequests[textureIndex].IsTarget(placeholderTexture)); + if (loadedMaterialIndex >= 0) + loadedDataAtMaterial[loadedMaterialIndex].lastFrameRequested = Time.frameCount; + } + + protected void AssignTargetTextures (Material material, int materialIndex) { + int textureIndex = 0; // Todo: currently only main texture is supported. + RequestLoadTexture(material, materialIndex, textureIndex, null); + } + + protected virtual Texture RequestLoadTexture (Material material, int materialIndex, int textureIndex, + System.Action onTextureLoaded) { + PlaceholderTextureMapping[] placeholderTextures = placeholderMap[materialIndex].textures; TargetReference targetReference = placeholderTextures[textureIndex].targetTextureReference; loadedDataAtMaterial[materialIndex].lastFrameRequested = Time.frameCount; #if UNITY_EDITOR if (!Application.isPlaying) { - if (targetReference.EditorTexture != null) + if (targetReference.EditorTexture != null) { material.mainTexture = targetReference.EditorTexture; - return; + if (onTextureLoaded != null) onTextureLoaded(targetReference.EditorTexture); + } + return targetReference.EditorTexture; } #endif MaterialOnDemandData materialData = loadedDataAtMaterial[materialIndex]; if (materialData.textureRequests[textureIndex].WasRequested) { Texture loadedTexture = GetAlreadyLoadedTexture(materialIndex, textureIndex); - if (loadedTexture != null) + if (loadedTexture != null) { material.mainTexture = loadedTexture; - return; + if (onTextureLoaded != null) onTextureLoaded(loadedTexture); + } + return loadedTexture; } - CreateTextureRequest(targetReference, materialData, textureIndex, material); + CreateTextureRequest(targetReference, materialData, textureIndex, material, onTextureLoaded); + return null; } public abstract Texture GetAlreadyLoadedTexture (int materialIndex, int textureIndex); public abstract void CreateTextureRequest (TargetReference targetReference, - MaterialOnDemandData materialData, int textureIndex, Material materialToUpdate); + MaterialOnDemandData materialData, int textureIndex, Material materialToUpdate, + System.Action onTextureLoaded); public virtual void UnloadUnusedTextures () { int currentFrameCount = Time.frameCount; diff --git a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/package.json b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/package.json index 5682f3443..88ff77e98 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/package.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.on-demand-loading/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.on-demand-loading", "displayName": "Spine On-Demand Loading Extensions [Experimental]", "description": "This experimental plugin provides a generic basic implementation of on-demand texture loading for the spine-unity runtime. You might want to use the available com.esotericsoftware.spine.addressables package which depends on this package.\nPlease be sure to test this package first and create backups of your project before using.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime (via the spine-unity unitypackage), version 4.1.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.1.0", + "version": "4.1.0-preview.2", "unity": "2018.3", "author": { "name": "Esoteric Software",