430 lines
16 KiB
C#
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);
|
|
} |