Files
back_cantanBuilding/Assets/Scripts/Others/RewardFlyBatchController.cs
2026-05-26 16:15:54 +08:00

170 lines
5.5 KiB
C#

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<IObjectPoolService>();
_rewardFlyPool = _objectPoolService.CreatePool(rewardFlyPrefab, initialPoolSize, maxPoolSize);
GContext.OnEvent<BatchedRewardFlyRequest>().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<BatchedRewardFly>();
try
{
int iconCount = 1;
if (request.Quantity.HasValue)
iconCount = Mathf.Clamp(request.Quantity.Value, 1, maxIconsPerRequest);
var taskList = new List<Task>();
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
{
/// <summary>
/// Global position of a transform
/// </summary>
public readonly Vector3 Pos;
/// <summary>
/// Literal size of a transform
/// </summary>
public readonly float Size;
/// <summary>
/// Lossy scale of a transform
/// </summary>
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;
}
}