Extension for LoadSubSprite

Extension for LoadSubSprite
This commit is contained in:
Alex-Rachel
2025-05-07 12:53:27 +08:00
parent 4c903e8da5
commit 1894cd4d72
3 changed files with 154 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
using System.Threading;
using Cysharp.Threading.Tasks;
using TEngine;
using UnityEngine;
using UnityEngine.UI;
@@ -27,4 +28,29 @@ public static class SetSpriteExtensions
{
ResourceExtComponent.Instance.SetAssetByResources<Sprite>(SetSpriteObject.Create(spriteRenderer, location, cancellationToken)).Forget();
}
/// <summary>
/// 设置子图片。
/// </summary>
/// <param name="image">UI/Image。</param>
/// <param name="location">资源定位地址。</param>
/// <param name="spriteName">子图片名称。</param>
/// <param name="setNativeSize">是否使用原始分辨率。</param>
/// <param name="cancellationToken">取消设置资源的Token。</param>
public static void SetSubSprite(this Image image, string location, string spriteName, bool setNativeSize = false, CancellationToken cancellationToken = default)
{
ResourceExtComponent.Instance.SetSubSprite(image, location, spriteName, setNativeSize, cancellationToken).Forget();
}
/// <summary>
/// 设置子图片。
/// </summary>
/// <param name="spriteRenderer">2D/SpriteRender。</param>
/// <param name="location">资源定位地址。</param>
/// <param name="spriteName">子图片名称。</param>
/// <param name="cancellationToken">取消设置资源的Token。</param>
public static void SetSubSprite(this SpriteRenderer spriteRenderer, string location, string spriteName, CancellationToken cancellationToken = default)
{
ResourceExtComponent.Instance.SetSubSprite(spriteRenderer, location, spriteName, cancellationToken).Forget();
}
}

View File

@@ -0,0 +1,125 @@
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 资源组件拓展。
/// </summary>
internal partial class ResourceExtComponent
{
private readonly Dictionary<string, SubAssetsHandle> _subAssetsHandles = new Dictionary<string, SubAssetsHandle>();
private readonly Dictionary<string, int> _subSpriteReferences = new Dictionary<string, int>();
public async UniTask SetSubSprite(Image image, string location, string spriteName, bool setNativeSize = false, CancellationToken cancellationToken = default)
{
var subSprite = await GetSubSpriteImp(location, spriteName, cancellationToken);
if (image == null)
{
Log.Warning($"SetSubAssets Image is null");
return;
}
image.sprite = subSprite;
if (setNativeSize)
{
image.SetNativeSize();
}
AddReference(image.gameObject, location);
}
public async UniTask SetSubSprite(SpriteRenderer spriteRenderer, string location, string spriteName, CancellationToken cancellationToken = default)
{
var subSprite = await GetSubSpriteImp(location, spriteName, cancellationToken);
if (spriteRenderer == null)
{
Log.Warning($"SetSubAssets Image is null");
return;
}
spriteRenderer.sprite = subSprite;
AddReference(spriteRenderer.gameObject, location);
}
private async UniTask<Sprite> GetSubSpriteImp(string location, string spriteName, CancellationToken cancellationToken = default)
{
var assetInfo = YooAssets.GetAssetInfo(location);
if (assetInfo.IsInvalid)
{
throw new GameFrameworkException($"Invalid location: {location}");
}
await TryWaitingLoading(location);
if (!_subAssetsHandles.TryGetValue(location, out var subAssetsHandle))
{
subAssetsHandle = YooAssets.LoadSubAssetsAsync<Sprite>(location);
await subAssetsHandle.ToUniTask(cancellationToken: cancellationToken);
_subAssetsHandles[location] = subAssetsHandle;
}
var subSprite = subAssetsHandle.GetSubAssetObject<Sprite>(spriteName);
if (subSprite == null)
{
throw new GameFrameworkException($"Invalid sprite name: {spriteName}");
}
return subSprite;
}
private void AddReference(GameObject target,string location)
{
var subSpriteReference = target.GetComponent<SubSpriteReference>();
if (subSpriteReference == null)
{
subSpriteReference = target.AddComponent<SubSpriteReference>();
}
_subSpriteReferences[location] = _subSpriteReferences.TryGetValue(location, out var count) ? count + 1 : 1;
subSpriteReference.Reference(location);
}
internal void DeleteReference(string location)
{
if (string.IsNullOrEmpty(location))
{
return;
}
_subSpriteReferences[location] = _subSpriteReferences.TryGetValue(location, out var count) ? count - 1 : 0;
if (_subSpriteReferences[location] <= 0)
{
var subAssetsHandle = _subAssetsHandles[location];
subAssetsHandle.Dispose();
_subAssetsHandles.Remove(location);
_subSpriteReferences.Remove(location);
}
}
}
[DisallowMultipleComponent]
public class SubSpriteReference : MonoBehaviour
{
private string _location;
public void Reference(string location)
{
if (_location != null && _location != location)
{
ResourceExtComponent.Instance?.DeleteReference(_location);
}
_location = location;
}
private void OnDestroy()
{
if (_location != null)
{
ResourceExtComponent.Instance?.DeleteReference(_location);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6ff32785e2bb42d085e53a36eb09038d
timeCreated: 1746582361