using asap.core; using asap.core.common; using cfg; using DG.Tweening; using System.Collections.Generic; using System.Threading.Tasks; using TMPro; using UnityEngine; using UnityEngine.UI; using GameCore; public struct CollectionItemFly { public int itemID; /// /// 没有ItemID 直接iconName /// public string iconName; /// /// 也可以直接放 icon Sprite /// public Sprite icon; public string numStr; public Vector2 scale; public float sourceIconSize; public float targetIconSize; public Vector3 sourcePos; public Vector3 destPos; //public float showDuration; //public float flyDuration; public bool isPlayOpen; public bool isPlayClose; public bool isDestinationRewardStash; } public class RewardFly : 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; public AnimationCurve curveX; public AnimationCurve curveY; public AnimationCurve curveScale; public float flyDuration = 0.4f; public float showDuration = 0.5f; public float closeAnimationDurationStash = 0.33f; public float closeAnimationDuration = 0.5f; // public float showTraceDelay = 0.05f; [SerializeField] protected GameObject fxTrace, iconRoot, fxRoot; protected const string IN = "rewardfly_show", OUT = "rewardfly_out", OUT_STASH = "rewardfly_out_bag", FLY = "rewardfly_fly", GeneratedFlag = "[generated]"; private IObjectPool _pool; [SerializeField] private ParticleSystem fxTrail; private void OnEnable() { // Debug.Log($"[RewardFly] Enabled."); icon.gameObject.SetActive(false); icon_card.gameObject.SetActive(false); icon_rod.gameObject.SetActive(false); } public virtual async Task ShowAsync(CollectionItemFly itemFly) { SetText(itemFly.numStr); if (itemFly.sourceIconSize != 0.0f) { var sourceScale = GetTransitionScale(itemFly.sourceIconSize); iconRoot.transform.localScale = new Vector3(sourceScale, sourceScale, 1f); } if (itemFly.icon != null) { SetData(itemFly.icon); } else if (string.IsNullOrEmpty(itemFly.iconName)) { SetData(itemFly.itemID); } else { SetData(itemFly.iconName); } // transform.localScale = itemFly.scale; transform.position = itemFly.sourcePos; if (itemFly.isPlayOpen) { ani.Play(IN); await Awaiters.Seconds(showDuration); // PlayOpen(); } else { //ani.Play("reward_common_idle"); } //ani.Play("reward_common_idle"); SetText(""); ShowTrace(); transform.DOMoveX(itemFly.destPos.x, flyDuration).SetEase(curveX); transform.DOMoveY(itemFly.destPos.y, flyDuration).SetEase(curveY); var targetScale = GetTransitionScale(itemFly.targetIconSize); iconRoot.transform.DOScale(targetScale, flyDuration).SetEase(curveScale); await Awaiters.Seconds(flyDuration); if (!itemFly.isPlayClose) return; if (itemFly.isDestinationRewardStash) { ani.Play(OUT_STASH); await Awaiters.Seconds(closeAnimationDurationStash); } else { ani.Play(OUT); await Awaiters.Seconds(closeAnimationDuration); } ShowTrace(); } public async void Show(CollectionItemFly itemFly) { try { await ShowAsync(itemFly); } catch (System.Exception e) { Debug.Log($"[RewardFly] {e.Message}\n{e.StackTrace}"); } } void PlayOpen() { ani.Play("reward_common_open"); } void PlayClose() { ani.Play("reward_common_close"); } protected void SetData(string iconName) { icon.gameObject.SetActive(true); GContext.container.Resolve().SetImageSprite(icon, iconName, BasePanel.PanelName); } protected void SetData(Sprite iconSprite) { icon.gameObject.SetActive(true); icon.sprite = iconSprite; } protected void SetText(string numStr) { text_num.gameObject.SetActive(true); text_num.text = numStr; } protected void SetData(int itemID) { Item item = GContext.container.Resolve().TbItem.GetOrDefault(itemID); if (item.Type == 5 && (item.SubType == 1 || item.SubType == 2)) { IUIService uiService = GContext.container.Resolve(); List BgNameList; if (item.SubType == 1) { var fishCard = GContext.container.Resolve().TbFishCardDrop.GetOrDefault(item.RedirectID); BgNameList = fishCard.BgNameList; } else { var fishCard = GContext.container.Resolve().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().SetImageSprite(icon_rod, item.Icon, BasePanel.PanelName); } else { icon.gameObject.SetActive(true); GContext.container.Resolve().SetImageSprite(icon, item.Icon, BasePanel.PanelName); } } protected float GetTransitionScale(float targetIconSize) { if (!icon.gameObject.TryGetComponent(out var iconRect)) { Debug.Log("[RewardFly] Cannot find icon RectTransform.", this); return 1; } var res = targetIconSize / iconRect.rect.width; return res; } protected void ShowTrace(bool doesShow = true) { // Debug.Log("[RewardFly] Trace Shown"); if (fxTrace != null) fxTrace.SetActive(doesShow); } public void OnSpawn() { // Debug.Log("[RewardFly] Spawn in Obj pool."); transform.SetParent(UIManager.Instance.RectTrans); transform.localScale = Vector3.one; text_num.gameObject.SetActive(true); 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); } } }