From 6f61a75bb7711876d03b73a00dfd29da39db2ccf Mon Sep 17 00:00:00 2001 From: Atony <75191600+AtonyGit@users.noreply.github.com> Date: Sat, 15 Aug 2026 13:18:05 -0500 Subject: [PATCH] Add BundleSubAssetHolder for packed spritesheets --- .../Patches/Options/RoleSettingMenuPatches.cs | 1 - .../Assets/LoadableBundleSubAsset.cs | 37 ++++++++ .../Assets/LoadableBundleSubAssetHolder.cs | 86 +++++++++++++++++++ MiraAPI/Utilities/Assets/TmpSpriteUtils.cs | 4 +- 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs create mode 100644 MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs index 0dc8721..65c64f6 100644 --- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs @@ -550,7 +550,6 @@ public static class RoleSettingMenuPatches new Rect(0, 0, 370, 230), Vector2.one / 2, 100); - __instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced; } __instance.roleHeaderSprite.color = customRole.OptionsMenuColor; diff --git a/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs b/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs new file mode 100644 index 0000000..ef7aea3 --- /dev/null +++ b/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using UnityEngine; + +namespace MiraAPI.Utilities.Assets; + +/// +/// A utility class for loading multiple assets from an . +/// +/// The name of the asset. +/// The that contains the asset. +public class LoadableBundleSubAsset(string name, LoadableBundleSubAssetHolder assetHolder) : LoadableAsset +{ + /// + /// Loads the asset from the . + /// + /// The asset. + /// The asset did not load properly. + public override Sprite LoadAsset() + { + if (LoadedAsset != null) + { + return LoadedAsset; + } + + assetHolder.TryInit(); + + var loadedAsset = assetHolder.SubSprites.FirstOrDefault(x => x.name == name); + + if (loadedAsset == null) + { + throw new InvalidOperationException($"INVALID ASSETS: {name}"); + } + LoadedAsset = loadedAsset; + return LoadedAsset; + } +} diff --git a/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs b/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs new file mode 100644 index 0000000..1599398 --- /dev/null +++ b/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs @@ -0,0 +1,86 @@ +using System; +using System.Linq; +using HarmonyLib; +using Il2CppInterop.Runtime; +using Reactor.Utilities.Extensions; +using UnityEngine; + +namespace MiraAPI.Utilities.Assets; + +/// +/// A utility class for loading multiple assets from an . +/// +public class LoadableBundleSubAssetHolder +{ + /// + /// Initializes a new instance of the class. + /// + /// The name of the assets to pull from. + /// The that contains the assets. + public LoadableBundleSubAssetHolder(string[] names, AssetBundle bundle) + { + Bundle = bundle; + SpriteNames = names; + } + + /// + /// Initializes a new instance of the class. + /// + /// The name of the asset. + /// The that contains the assets. + public LoadableBundleSubAssetHolder(string name, AssetBundle bundle) + { + Bundle = bundle; + SpriteNames = [name]; + } + internal string[] SpriteNames = []; + internal AssetBundle Bundle; + public Sprite[] SubSprites = []; + + public virtual void TryInit() + { + if (SubSprites.Length == 0) + { + var newSprites = Array.Empty(); + foreach (var name in SpriteNames) + { + var loadedAssets = Bundle.LoadAssetWithSubAssets(name, Il2CppType.From(typeof(Sprite))).ToArray(); + + if (loadedAssets == null) + { + throw new InvalidOperationException($"INVALID ASSETS: {name}"); + } + foreach (var obj in loadedAssets) + { + var img = obj.TryCast(); + if (img != null) + { + img.DontDestroy().DontUnload(); + newSprites = newSprites.AddToArray(img); + } + } + } + + SubSprites = newSprites; + } + } + + /// + /// Unloads an asset. + /// + /// True if the asset was unloaded, false otherwise. + public bool UnloadAsset() + { + if (SubSprites.Length == 0) + { + return false; + } + + foreach (var sprite in SubSprites) + { + sprite.DestroyImmediate(); + } + SubSprites = []; + return true; + } +} diff --git a/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs b/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs index 518e4ac..6160a01 100644 --- a/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs +++ b/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs @@ -71,8 +71,8 @@ public static class TmpSpriteUtils { name = spriteName, hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteName), - x = 0, - y = 0, + x = rect.x, + y = rect.y, width = rect.width, height = rect.height, xOffset = -(rect.width / 3) + (scale - 1) * (rect.width / 2),