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

430 lines
16 KiB
C#

using asap.core;
using asap.core.common;
using cfg;
using DG.Tweening;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using GameCore;
using System;
using Game;
using TMPro;
public class BatchedRewardFly : MonoBehaviour, IPoolableObject
{
public Image icon;
public Image icon_card;
public Image icon_card_logo;
public Image icon_card_num;
public Image icon_rod;
public TMP_Text text_num;
public Animation ani;
[SerializeField] private GameObject /*fxTrace, */iconRoot, fxRoot;
[SerializeField] private CanvasGroup canvasGroup;
[SerializeField] private ParticleSystem fxTrail;
private const string IN = "rewardfly_show_batched", OUT = "rewardfly_out_batched", OUT_STASH = "rewardfly_out_bag_batched",
FLY_BATCHED = "rewardfly_fly_batched", FLY_SINGLE = "rewardfly_fly_single", GeneratedFlag = "[generated]", IN_SINGLE = "rewardfly_show_single";
private IObjectPool _pool;
private readonly DefaultRectTr DefaultLocalTextTransform = new DefaultRectTr();
private void OnEnable()
{
// Debug.Log($"[RewardFly] Enabled.", this);
icon.gameObject.SetActive(false);
icon_card.gameObject.SetActive(false);
icon_rod.gameObject.SetActive(false);
}
public virtual async Task SingleFlyAsync(BatchedRewardFlyRequest request, RewardFlyAnimationParams para)
{
// Debug.Log($"[RewardFly] SingleFly");
ani.Play(FLY_SINGLE);
SetText("");
canvasGroup.alpha = para.alphaShow;
iconRoot.transform.localScale = Vector3.one;
if (request.StartPoint.Size != 0.0f)
{
var sourceScale = GetTransitionScale(request.StartPoint.Size, request.StartPoint.LossyScale);
iconRoot.transform.localScale = sourceScale * para.scaleShow * Vector3.one;
iconRoot.transform.DOScale(sourceScale, para.ShowDuration).SetEase(para.CurveShow);
}
else
{
iconRoot.transform.localScale = para.scaleShow * Vector3.one;
iconRoot.transform.DOScale(1, para.ShowDuration).SetEase(para.CurveShow);
}
if (request.icon != null)
SetData(request.icon);
else if (string.IsNullOrEmpty(request.iconName))
SetData(request.itemID);
else
SetData(request.iconName);
transform.position = request.StartPoint.Pos;
// if (request.sourceTextRt != null)
// {
// var rt = text_num.transform as RectTransform;
// rt.anchorMin = request.sourceTextRt.anchorMin;
// rt.anchorMax = request.sourceTextRt.anchorMax;
// rt.pivot = request.sourceTextRt.pivot;
// rt.anchoredPosition = request.sourceTextRt.anchoredPosition;
// rt.sizeDelta = request.sourceTextRt.sizeDelta;
// }
// else
// {
// var rt = text_num.transform as RectTransform;
// rt.anchorMin = DefaultLocalTextTransform.anchorMin;
// rt.anchorMax = DefaultLocalTextTransform.anchorMax;
// rt.pivot = DefaultLocalTextTransform.pivot;
// rt.anchoredPosition = DefaultLocalTextTransform.anchoredPosition;
// rt.sizeDelta = DefaultLocalTextTransform.sizeDelta;
// }
if (para.IsPlayOpen)
{
OpenFx(ERewardFlyStage.Show, para.FxSingle, out var fx);
ani.Play(IN_SINGLE);
await transform.DOMove(request.StartPoint.Pos, para.ShowDuration).SetEase(Ease.InOutSine).AsyncWaitForCompletion();
CloseFx(fx);
}
string audioFly = para.GetAudioUrl(1, request.Quantity != null && request.Quantity.Value > 1);
GContext.Publish(new EventUISound(audioFly));
OpenFx(ERewardFlyStage.Fly, para.FxSingle, out var flyFx);
transform.DOMoveX(request.EndPoint.Pos.x, para.FlyDuration).SetEase(para.CurveX);
transform.DOMoveY(request.EndPoint.Pos.y, para.FlyDuration).SetEase(para.CurveY);
var targetScale = GetTransitionScale(request.EndPoint.Size, request.EndPoint.LossyScale);
iconRoot.transform.DOScale(targetScale, para.FlyDuration).SetEase(para.CurveScale);
iconRoot.transform.DORotate(Vector3.zero, para.FlyDuration).SetEase(Ease.InOutSine);
await Awaiters.Seconds(para.FlyDuration);
CloseFx(flyFx);
if (!para.IsPlayClose)
{
return;
}
OpenFx(request.isDestinationRewardStash ? ERewardFlyStage.OutStash : ERewardFlyStage.Out, para.FxSingle, out var outFx);
if (request.isDestinationRewardStash)
{
ani.Play(OUT_STASH);
}
else
{
ani.Play(OUT);
}
string audioOut = para.GetAudioUrl(2, request.Quantity != null && request.Quantity.Value > 1);
GContext.Publish(new EventUISound(audioOut));
await Awaiters.Seconds(para.CloseDuration);
CloseFx(outFx);
}
public virtual async Task BatchShowAsync(BatchedRewardFlyRequest request, RewardFlyAnimationParams para)
{
// Debug.Log($"[RewardFly] BatchShow");
canvasGroup.alpha = 1f;
iconRoot.transform.localScale = Vector3.one;
SetText(request.Quantity, request.itemID);
float sourceScale = 1;
if (request.StartPoint.Size != 0.0f)
{
sourceScale = GetTransitionScale(request.StartPoint.Size, request.StartPoint.LossyScale);
iconRoot.transform.localScale = new Vector3(sourceScale, sourceScale, 1f);
}
else
{
iconRoot.transform.localScale = para.scaleShow * Vector3.one;
iconRoot.transform.DOScale(1, para.ShowDuration).SetEase(para.CurveShow);
}
if (request.icon != null)
SetData(request.icon);
else if (string.IsNullOrEmpty(request.iconName))
SetData(request.itemID);
else
SetData(request.iconName);
transform.position = request.StartPoint.Pos;
if (request.sourceTextRt != null)
{
var rt = text_num.GetComponent<RectTransform>();
rt.anchorMin = request.sourceTextRt.anchorMin;
rt.anchorMax = request.sourceTextRt.anchorMax;
rt.anchoredPosition = request.sourceTextRt.anchoredPosition;
rt.sizeDelta = request.sourceTextRt.sizeDelta;
rt.pivot = request.sourceTextRt.pivot;
}
else
{
var rt = text_num.GetComponent<RectTransform>();
rt.anchorMin = DefaultLocalTextTransform.anchorMin;
rt.anchorMax = DefaultLocalTextTransform.anchorMax;
rt.anchoredPosition = DefaultLocalTextTransform.anchoredPosition;
rt.sizeDelta = DefaultLocalTextTransform.sizeDelta;
rt.pivot = DefaultLocalTextTransform.pivot;
}
OpenFx(ERewardFlyStage.Show, para.FxBatched, out var fx);
ani.Play(IN);
await Task.Delay(TimeSpan.FromSeconds(para.ShowDuration));
CloseFx(fx);
}
public virtual async Task BatchFlyAsync(BatchedRewardFlyRequest request, RewardFlyAnimationParams para)
{
// Debug.Log($"[RewardFly] BatchFly");
ani.Play(FLY_BATCHED);
SetText("");
canvasGroup.alpha = para.alphaShow;
iconRoot.transform.localScale = Vector3.one;
if (request.StartPoint.Size != 0.0f)
{
var sourceScale = GetTransitionScale(request.StartPoint.Size, request.StartPoint.LossyScale) *
(request.Quantity != null && request.Quantity.Value > 1 ? para.MultipleIconScaleModifier : 1f);
iconRoot.transform.localScale = sourceScale * para.scaleShow * Vector3.one;
iconRoot.transform.DOScale(sourceScale, para.ShowDuration).SetEase(para.CurveShow);
}
else
{
iconRoot.transform.localScale = para.scaleShow * Vector3.one;
iconRoot.transform.DOScale(1, para.ShowDuration).SetEase(para.CurveShow);
}
if (request.icon != null)
SetData(request.icon);
else if (string.IsNullOrEmpty(request.iconName))
SetData(request.itemID);
else
SetData(request.iconName);
transform.position = request.StartPoint.Pos;
var delta = Vector3.zero;
if (para.IsPlayOpen)
{
if (request.Quantity != null && request.Quantity > 1)
{
// ani.Play(IN);
delta = (Vector3)FtMathUtils.GetCornSpread(para.SpreadHalfAngle, para.SpreadNearRange, para.SpreadFarRange);
if (para.MaxTiltAngle > 0)
{
var angle = UnityEngine.Random.Range(-para.MaxTiltAngle, para.MaxTiltAngle);
iconRoot.transform.DORotate(new Vector3(0, 0, angle), para.ShowDuration).SetEase(Ease.InOutSine);
}
}
canvasGroup.DOFadeAlpha(1f, para.ShowDuration).SetEase(para.CurveShow);
await transform.DOMove(request.StartPoint.Pos + delta, para.ShowDuration).SetEase(Ease.InOutSine).AsyncWaitForCompletion();
}
string audioFly = para.GetAudioUrl(1, request.Quantity != null && request.Quantity.Value > 1);
GContext.Publish(new EventUISound(audioFly));
// SetText("");
// ShowTrace();
OpenFx(ERewardFlyStage.Fly, para.FxBatched, out var fx);
transform.DOMoveX(request.EndPoint.Pos.x, para.FlyDuration).SetEase(para.CurveX);
transform.DOMoveY(request.EndPoint.Pos.y, para.FlyDuration).SetEase(para.CurveY);
var targetScale = GetTransitionScale(request.EndPoint.Size, request.EndPoint.LossyScale);
iconRoot.transform.DOScale(targetScale, para.FlyDuration).SetEase(para.CurveScale);
iconRoot.transform.DORotate(Vector3.zero, para.FlyDuration).SetEase(Ease.InOutSine);
await Awaiters.Seconds(para.FlyDuration);
CloseFx(fx);
if (!para.IsPlayClose)
{
return;
}
OpenFx(request.isDestinationRewardStash ? ERewardFlyStage.OutStash : ERewardFlyStage.Out, para.FxBatched, out var outFx);
if (request.isDestinationRewardStash)
{
ani.Play(OUT_STASH);
// Debug.Log("[RewardFly] PlayClose OUT_STASH", this);
}
else
{
ani.Play(OUT);
// Debug.Log("[RewardFly] PlayClose OUT", this);
}
string audioOut = para.GetAudioUrl(2, request.Quantity != null && request.Quantity.Value > 1);
GContext.Publish(new EventUISound(audioOut));
await Awaiters.Seconds(para.CloseDuration);
CloseFx(outFx);
// Debug.Log("[RewardFly] PlayClose Done", this);
}
void PlayOpen()
{
ani.Play("reward_common_open");
}
void PlayClose()
{
ani.Play("reward_common_close");
}
void SetData(string iconName)
{
icon.gameObject.SetActive(true);
GContext.container.Resolve<IUIService>().SetImageSprite(icon, iconName, BasePanel.PanelName);
}
void SetData(Sprite iconSprite)
{
icon.gameObject.SetActive(true);
icon.sprite = iconSprite;
}
void SetText(string numStr)
{
text_num.gameObject.SetActive(true);
text_num.text = numStr;
}
void SetText(int? quantity, int itemId)
{
if (quantity.HasValue && quantity.Value > 1)
{
var value = quantity.Value;
if (itemId == 1002)
value = value = ConvertTools.KeepThreeSignificantDigits(value);
SetText("x" + ConvertTools.GetNumberString(value));
}
else
SetText("");
}
void SetData(int itemID)
{
Item item = GContext.container.Resolve<Tables>().TbItem.GetOrDefault(itemID);
if (item.Type == 5 && (item.SubType == 1 || item.SubType == 2))
{
IUIService uiService = GContext.container.Resolve<IUIService>();
List<string> BgNameList;
if (item.SubType == 1)
{
var fishCard = GContext.container.Resolve<Tables>().TbFishCardDrop.GetOrDefault(item.RedirectID);
BgNameList = fishCard.BgNameList;
}
else
{
var fishCard = GContext.container.Resolve<Tables>().TbGeneralCardWeight.GetOrDefault(item.RedirectID);
BgNameList = fishCard.BgNameList;
}
uiService.SetImageSprite(icon_card, BgNameList[0], BasePanel.PanelName);
uiService.SetImageSprite(icon_card_logo, BgNameList[1], BasePanel.PanelName);
uiService.SetImageSprite(icon_card_num, BgNameList[2], BasePanel.PanelName);
icon_card.gameObject.SetActive(true);
}
else if (item.Type == 3 && (item.SubType == 1 || item.SubType == 3))
{
icon_rod.gameObject.SetActive(true);
GContext.container.Resolve<IUIService>().SetImageSprite(icon_rod, item.Icon, BasePanel.PanelName);
}
else
{
icon.gameObject.SetActive(true);
GContext.container.Resolve<IUIService>().SetImageSprite(icon, item.Icon, BasePanel.PanelName);
}
}
private float GetTransitionScale(float targetIconSize, float targetLossyScale)
{
if (!icon.gameObject.TryGetComponent<RectTransform>(out var iconRect))
{
Debug.Log("[RewardFly] Cannot find icon RectTransform.", this);
return 1;
}
// This is hard core.
var res = targetIconSize * targetLossyScale / (iconRect.rect.width * iconRect.lossyScale.x / iconRoot.transform.localScale.x / iconRect.localScale.x);
// Debug.Log($"[RewardFly] res {res} = {targetIconSize} * {targetLossyScale} / ({iconRect.rect.width} * {iconRect.lossyScale.x} / {iconRoot.transform.localScale.x} / {iconRect.localScale.x})", this);
return res;
}
public void OnSpawn()
{
// Debug.Log("[RewardFly] Spawn in Obj pool.");
transform.SetParent(UIManager.Instance.RectTrans);
transform.localScale = Vector3.one;
// text_num.gameObject.SetActive(false);
iconRoot.transform.localScale = Vector3.one;
// ani.Play(FLY);
}
public void OnDespawn()
{
// Debug.Log("[RewardFly] Despawn in Obj pool.");
// ShowTrace(false);
RemoveGeneratedRenderer(fxRoot);
// transform.SetParent(UIManager.Instance.RectTrans);
}
public void OnPoolCreate(IObjectPool objectPool)
{
_pool = objectPool;
// Debug.Log("[RewardFly] Created in pool.");
}
public void OnPoolDestroy()
{
_pool = null;
}
public void ReturnPool()
{
_pool?.DespawnObject(this);
}
private void RemoveGeneratedRenderer(GameObject go)
{
var cc = go.transform.childCount;
if (cc > 0)
{
for (int i = 0; i < cc; i++)
{
var child = go.transform.GetChild(i).gameObject;
RemoveGeneratedRenderer(child);
}
}
if (go.name.StartsWith(GeneratedFlag))
{
Destroy(go);
}
}
private void OpenFx(ERewardFlyStage stage, string[] fxList, out GameObject fx)
{
fx = null;
try
{
if (fxList != null && fxList.Length > (int)stage)
{
var tr = transform.Find("FxRoot/" + fxList[(int)stage]);
if (tr != null)
fx = tr.gameObject;
if (fx != null)
fx.SetActive(true);
else
Debug.Log($"[BatchedRewardFly] Fx not found: \"{fxList[(int)stage]}\"", this);
}
}
catch (Exception e)
{
Debug.Log($"[BatchedRewardFly] OpenFx Error: {e.Message}\n{e.StackTrace}", this);
}
}
private void CloseFx(GameObject fx)
{
if (fx != null)
fx.SetActive(false);
}
}
public enum ERewardFlyStage
{
Show = 0,
Fly = 1,
Out = 2,
OutStash = 3
}
public class DefaultRectTr
{
public Vector2 anchorMax = 0.5f * Vector2.one;
public Vector2 anchorMin = 0.5f * Vector2.one;
public Vector2 pivot = 0.5f * Vector2.one;
public Vector2 anchoredPosition = new Vector2(0, -94);
public Vector2 sizeDelta = new Vector2(166, 56);
}