using asap.core; using asap.core.common; using UnityEngine; using UniRx; using System.Threading.Tasks; using System.Collections.Generic; using Game; using UnityEngine.UI; using GameCore; public class RewardFlyBatchController : MonoBehaviour { [Header("Configuration")] [SerializeField] private BatchedRewardFly rewardFlyPrefab; [SerializeField] private int initialPoolSize = 5; [SerializeField] private int maxPoolSize = 20; [SerializeField] private int maxIconsPerRequest = 8; [Header("Animation Parameters")] [SerializeField] private RewardFlyAnimationParams[] animationParamList; // public IEventAggregator EventBus { get; private set; } private IObjectPoolService _objectPoolService; private IObjectPool _rewardFlyPool; void Awake() { _objectPoolService = GContext.container.Resolve(); _rewardFlyPool = _objectPoolService.CreatePool(rewardFlyPrefab, initialPoolSize, maxPoolSize); GContext.OnEvent().Subscribe(OnRewardFlyRequest).AddTo(this); } void OnDestroy() { _objectPoolService?.DestroyPool(typeof(BatchedRewardFly)); _rewardFlyPool = null; } public async void OnRewardFlyRequest(BatchedRewardFlyRequest request) { try { await OnRewardFlyRequestAsync(request); } catch (System.Exception ex) { Debug.LogError(ex); } } public async Task OnRewardFlyRequestAsync(BatchedRewardFlyRequest request) { var rewardFlyList = new List(); try { int iconCount = 1; if (request.Quantity.HasValue) iconCount = Mathf.Clamp(request.Quantity.Value, 1, maxIconsPerRequest); var taskList = new List(); var param = animationParamList[request.AnimationParamIndex]; // if (param.IsPlayOpen) // GContext.Publish(new EventUISound("audio_ui_rewardfly_single_fly")); string audioShow = param.GetAudioUrl(0, iconCount > 1); GContext.Publish(new EventUISound(audioShow)); BatchedRewardFly rewardFly; //Show if (iconCount <= 1) { rewardFly = _rewardFlyPool.SpawnObject() as BatchedRewardFly; if (rewardFly == null) { Debug.LogError("[RewardFlyBatchController] Failed to spawn RewardFly from pool."); return; } rewardFlyList.Add(rewardFly); rewardFly.gameObject.SetActive(true); await rewardFly.SingleFlyAsync(request, param); } else { rewardFly = _rewardFlyPool.SpawnObject() as BatchedRewardFly; if (rewardFly == null) { Debug.LogError("[RewardFlyBatchController] Failed to spawn RewardFly from pool."); return; } rewardFlyList.Add(rewardFly); rewardFly.gameObject.SetActive(true); await rewardFly.BatchShowAsync(request, param); for (int i = 0; i < iconCount; i++) { rewardFly = _rewardFlyPool.SpawnObject() as BatchedRewardFly; if (rewardFly == null) { Debug.LogError("[RewardFlyBatchController] Failed to spawn RewardFly from pool."); continue; } rewardFlyList.Add(rewardFly); rewardFly.gameObject.SetActive(true); taskList.Add(rewardFly.BatchFlyAsync(request, param)); if (iconCount > 1) { await Task.Delay(System.TimeSpan.FromSeconds(param.SpawnInterval)); } } await Task.WhenAll(taskList.ToArray()); } rewardFlyList.ForEach(rf => rf.ReturnPool()); rewardFlyList.Clear(); } catch (System.Exception e) { Debug.Log($"[RewardFlyBatchController] {e.Message}\n{e.StackTrace}"); rewardFlyList.ForEach(rf => Destroy(rf.gameObject)); rewardFlyList.Clear(); } // Debug.Log("[RewardFlyBatchController] Done."); } } public class BatchedRewardFlyRequest { // Pick one of these three, things just work. public int itemID; public string iconName; public Sprite icon; public int? Quantity; public BatchedRewardFlyPoint StartPoint; public BatchedRewardFlyPoint EndPoint; public RectTransform sourceTextRt = null; public bool isDestinationRewardStash; public int AnimationParamIndex; public BatchedRewardFlyRequest() { } } public class BatchedRewardFlyPoint { /// /// Global position of a transform /// public readonly Vector3 Pos; /// /// Literal size of a transform /// public readonly float Size; /// /// Lossy scale of a transform /// public readonly float LossyScale; public BatchedRewardFlyPoint(Vector3 pos, float size, float lossyScale) { Pos = pos; Size = size; LossyScale = lossyScale; } public BatchedRewardFlyPoint(Vector3 pos) { Pos = pos; Size = 0f; LossyScale = 1f; } public BatchedRewardFlyPoint(RectTransform t) { Pos = t.position; Size = t.sizeDelta.x; LossyScale = t.lossyScale.x; } }