using BingoBrain.Core; using UnityEditor; using UnityEngine.Events; namespace BingoBrain.Asset { using System; using System.Linq; using UnityEngine; using System.Collections.Generic; using Object = UnityEngine.Object; using BingoBrain.Asset.Editor; public class BetKit : Singleton { private readonly Dictionary> mGameObject2AbMap = new(); private readonly Dictionary> mSprite2AbMap = new(); private readonly Dictionary> mAudio2AbMap = new(); private IBigose LoadAssetType { get; set; } public void Init(IBigose loadAssetType = null) { //#if UNITY_EDITOR LoadAssetType = new BingoseKit(); // #else // LoadAssetType = loadAssetType ?? new AssetBundleKit(); // #endif } public void LoadAsset(string assetUrl, string assetName, UnityAction onCompleted, bool isRecord = true) where T : Object { if (string.IsNullOrEmpty(assetUrl) || string.IsNullOrEmpty(assetName)) { Debug.LogError("AssetUrl or AssetName is Empty."); onCompleted?.Invoke(default); return; } Init(); if (LoadAssetType == null) { Debug.LogError("Please Call LoadBox.Instance.Init() first."); onCompleted?.Invoke(default); return; } LoadAssetType.GetAsset(assetUrl, assetName, (obj) => { if (obj != null && isRecord) { RecordGameObject(assetUrl, obj); } onCompleted?.Invoke(obj); }); } public T LoadAsset(string assetUrl, string assetName, bool isRecord = true) where T : Object { if (string.IsNullOrEmpty(assetUrl) || string.IsNullOrEmpty(assetName)) { Debug.LogError("AssetUrl or AssetName is Empty."); return default; } Init(); if (LoadAssetType == null) { Debug.LogError("Please Call LoadBox.Instance.Init() first."); return default; } var obj = LoadAssetType.GetAsset(assetUrl, assetName); if (obj != null && isRecord) { RecordGameObject(assetUrl, obj); } return obj; } #region 加载Sprite相关 public void LoadSprite(string assetUrl, string assetName, UnityAction onCompleted, bool isRecord = true) { LoadAsset(assetUrl, assetName, onCompleted, isRecord); } public Sprite LoadSprite(string assetUrl, string assetName, bool isRecord = true) { return LoadAsset(assetUrl, assetName, isRecord); } public void LoadSprite(string assetUrl, Action onCompleted) { if (string.IsNullOrEmpty(assetUrl)) { Debug.LogError("AssetUrl is Empty."); onCompleted?.Invoke(null); return; } Init(); if (LoadAssetType == null) { Debug.LogError("Please Call LoadKit.Instance.Init() first."); onCompleted?.Invoke(null); return; } string assetName; if (assetUrl.Contains("/")) { assetName = assetUrl.Split('/').Last(); assetUrl = assetUrl.Replace($"/{assetName}", string.Empty); } else { assetName = assetUrl.Split('.').Last(); assetUrl = assetUrl.Replace($".{assetName}", string.Empty); } LoadAssetType.GetAsset(assetUrl, assetName, delegate(Sprite sprite) { if (sprite != null) { RecordSprite(assetUrl, sprite); } onCompleted?.Invoke(sprite); }); } public void RecordSprite(string assetName, Sprite sprite) { if (sprite == null || string.IsNullOrEmpty(assetName)) { Debug.LogError("ABName is Null or Sprite is Null"); return; } var instanceId = sprite.GetInstanceID(); if (mSprite2AbMap.Keys.Contains(assetName)) { if (!mSprite2AbMap[assetName].Keys.Contains(instanceId)) { mSprite2AbMap[assetName].Add(instanceId, sprite.name); } } else { var spriteNameIns = new Dictionary { { instanceId, sprite.name } }; mSprite2AbMap.Add(assetName, spriteNameIns); } } #endregion #region 加载GameObject相关 public GameObject LoadGameObject(string assetUrl, string assetName, bool isRecord = true) { return LoadAsset(assetUrl, assetName, isRecord); } public void LoadGameObjectAndClone(string assetUrl, string assetName, UnityAction onCompleted = null, Transform parent = null, bool worldPositionStays = false) { LoadAsset(assetUrl, assetName, gameObject => { InstantiateAndRecord(gameObject, parent, worldPositionStays, onCompleted); }, false); } public GameObject LoadGameObjectAndCloneSync(string assetUrl, string assetName, Transform parent = null, bool worldPositionStays = false) { var gameObject = LoadGameObject(assetUrl, assetName, false); return InstantiateAndRecord(gameObject, parent, worldPositionStays); } public void RecordGameObject(string assetName, Object gameObject) { if (gameObject == null || string.IsNullOrEmpty(assetName)) { Debug.LogError("ABName is Null or Sprite is Null"); return; } var instanceId = gameObject.GetInstanceID(); if (mGameObject2AbMap.Keys.Contains(assetName)) { if (!mGameObject2AbMap[assetName].Keys.Contains(instanceId)) { mGameObject2AbMap[assetName].Add(instanceId, gameObject.name); } } else { var gameNameIns = new Dictionary { { instanceId, gameObject.name } }; mGameObject2AbMap.Add(assetName, gameNameIns); } } public GameObject InstantiateAndRecord(GameObject gameObject, Transform parent = null, bool worldPositionStays = false, UnityAction onCompleted = null) { if (gameObject == null) { Debug.LogError("GameObject is Null"); return null; } var newGameObject = parent ? Object.Instantiate(gameObject, parent, worldPositionStays) : Object.Instantiate(gameObject); if (newGameObject != null) { RecordCloneGameObject(gameObject, newGameObject); } onCompleted?.Invoke(newGameObject); return newGameObject; } private void RecordCloneGameObject(GameObject gameObject, GameObject newGameObject) { if (gameObject == null || newGameObject == null) { return; } var oldInstanceId = gameObject.GetInstanceID(); var instanceId = newGameObject.GetInstanceID(); foreach (var keyValuePair in mGameObject2AbMap) { if (!keyValuePair.Value.Keys.Contains(oldInstanceId) || keyValuePair.Value.Keys.Contains(instanceId)) continue; keyValuePair.Value.Add(instanceId, newGameObject.name); break; } } #endregion #region 加载声音相关 public void LoadAudio(string assetUrl, string assetName, UnityAction onCompleted) { LoadAsset(assetUrl, assetName, onCompleted); } #endregion public void RecycleAsset(string assetUrl, UnityAction onCompleted = null) { Init(); if (LoadAssetType != null) { LoadAssetType.RecycleAsset(assetUrl, onCompleted); } else { Debug.LogError("Please Call LoadBox.Instance.Init() first."); } } } }