geometry-tower-defense/Assets/GameMain/Scripts/CustomComponent/SpriteCacheComponent.cs

100 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using GameFramework.Resource;
using GeometryTD.CustomUtility;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace GeometryTD.CustomComponent
{
public class SpriteCacheComponent : GameFrameworkComponent
{
[SerializeField] private float _pixelsPerUnit = 100f;
[SerializeField] private Vector2 _defaultPivot = new(0.5f, 0.5f);
private Dictionary<string, Sprite> _spriteCache;
private Dictionary<string, List<Action<Sprite>>> _pendingCallbacks;
private ResourceComponent _resource;
void Start()
{
_spriteCache = new Dictionary<string, Sprite>();
_pendingCallbacks = new Dictionary<string, List<Action<Sprite>>>();
_resource = GameEntry.Resource;
}
public void GetSprite(string assetName, Action<Sprite> callback)
{
if (_spriteCache.TryGetValue(assetName, out var sprite))
{
callback?.Invoke(sprite);
return;
}
if (_pendingCallbacks.TryGetValue(assetName, out var pendingList))
{
pendingList.Add(callback);
return;
}
_pendingCallbacks[assetName] = new List<Action<Sprite>> { callback };
_resource.LoadAsset
(
AssetUtility.GetTextureAsset(assetName),
Constant.AssetPriority.UIFormAsset,
new LoadAssetCallbacks(
(resourcePath, asset, duration, userData) =>
{
Log.Debug(resourcePath);
Texture2D texture = asset as Texture2D;
Sprite loadedSprite = null;
if (texture != null)
{
loadedSprite = Sprite.Create(
texture,
new Rect(0, 0, texture.width, texture.height),
_defaultPivot,
_pixelsPerUnit);
_spriteCache[assetName] = loadedSprite;
}
if (_pendingCallbacks.TryGetValue(assetName, out var callbacks))
{
_pendingCallbacks.Remove(assetName);
for (int i = 0; i < callbacks.Count; i++)
{
callbacks[i]?.Invoke(loadedSprite);
}
}
},
(resourcePath, status, errorMessage, userData) =>
{
Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.",
assetName,
resourcePath,
errorMessage);
if (_pendingCallbacks.TryGetValue(assetName, out var callbacks))
{
_pendingCallbacks.Remove(assetName);
for (int i = 0; i < callbacks.Count; i++)
{
callbacks[i]?.Invoke(null);
}
}
}
)
);
}
private void OnDestroy()
{
_spriteCache.Clear();
_pendingCallbacks.Clear();
_resource = null;
}
}
}