using asap.core; using DG.Tweening; using EnhancedUI.EnhancedScroller; using System; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UI; namespace Assets.Scripts.UI.JigsawPuzzle { public class JigsawPuzzlePictureCell : EnhancedScrollerCellView { private Animation puzzle_completed; [Header("piece ani")] [SerializeField] private Vector3 startPostion = Vector3.zero; [SerializeField] private Vector3 startScale = Vector3.zero; [SerializeField] private Vector3 startRotation = Vector3.zero; [SerializeField, Min(0)] private float time = 0.5f; [SerializeField, Min(0)] private float delayDestroyTime = 1.3f; [SerializeField] private AnimationCurve firstCurve; private Image[] pieceImgs; private GameObject[] pieceObjs; private Image photo; private string fxName = "fx_ui_jigsawpuzzlebuilding_snap_flash"; public int PieceCount => pieceObjs?.Length ?? 6; private void Awake() { var pieceParentObj = this.gameObject.FindChildGameObject("p_piece"); pieceImgs = pieceParentObj.GetComponentsInChildren(true); pieceObjs = pieceParentObj.FindGameObjects(new string[] { "piece1", "piece2", "piece3", "piece4", "piece5", "piece6" }); photo = this.gameObject.FindChildGameObject(nameof(photo)).GetComponent(); puzzle_completed = this.GetComponent(); InitUI(); } private void InitUI() { photo.gameObject.SetActive(false); foreach (var piece in pieceObjs) { piece.gameObject.SetActive(false); piece.FindChildGameObject(fxName)?.SetActive(false); } } private List _unlockPieces; private string _name; public void SetData(List unlockPieces, string pictureName, bool isDelayShow) { if (_unlockPieces == null) _unlockPieces = new List(); _unlockPieces.Clear(); // 添加去重逻辑 if (unlockPieces != null) { foreach (var piece in unlockPieces) { // 验证有效性并去重 if (piece < 1 || piece > PieceCount) { Debug.LogError($"{this.GetType().Name} Invalid piece index: {piece}"); continue; } if (!_unlockPieces.Contains(piece)) _unlockPieces.Add(piece); else Debug.LogWarning($"{this.GetType().Name} Duplicate piece index detected: {piece}"); } } if (isDelayShow && _unlockPieces.Count > 0) { _unlockPieces.RemoveAt(_unlockPieces.Count - 1); } _name = pictureName; } public override void RefreshCellView() { ShowUI(); } public async void ShowUI() { try { if (pieceObjs == null || pieceObjs.Length == 0) return; foreach (var piece in pieceObjs) { piece.gameObject.SetActive(false); piece.FindChildGameObject(fxName)?.SetActive(false); } if (_unlockPieces == null) return; if (_unlockPieces.Count == pieceObjs.Length) { await GContext.container.Resolve().SetImageSprite(photo, _name); photo.gameObject.SetActive(true); } else { photo.gameObject.SetActive(false); foreach (var pieceIndexFrom1 in _unlockPieces) { if (pieceIndexFrom1 < 1 || pieceIndexFrom1 > pieceObjs.Length || pieceIndexFrom1 > pieceImgs.Length) continue; pieceObjs[pieceIndexFrom1 - 1].SetActive(true); var pieceImg = pieceImgs[pieceIndexFrom1 - 1]; var imgName = $"{_name}_{pieceIndexFrom1}"; await GContext.container.Resolve().SetImageSprite(pieceImg, imgName); } } } catch (Exception e) { Debug.LogError(e); } } public async Task PlayFly(int indexFrom1, bool isLastPiece,Action positonEndCallback=null) { if (indexFrom1 < 1 || indexFrom1 > pieceObjs.Length || indexFrom1 > pieceImgs.Length) { Debug.LogError($"{this.GetType().Name} 没找到这个碎片,index {indexFrom1}"); return; } if (isLastPiece) photo.gameObject.SetActive(false); var pieceObj = pieceObjs[indexFrom1 - 1]; pieceObj.SetActive(false); var pieceImg = pieceImgs[indexFrom1 - 1]; var imgName = $"{_name}_{indexFrom1}"; await GContext.container.Resolve() .SetImageSprite(pieceImg, imgName); //用于第一次加载图集比较慢的 if (pieceImg) { while (pieceImg != null&& pieceImg.sprite!=null &&!pieceImg.sprite.name.Contains(imgName)) { await Awaiters.NextFrame; } } var newPieceObj = Instantiate(pieceObj); if (newPieceObj == null) { Debug.LogError($"{this.GetType().Name} newPieceObj is null"); return; } newPieceObj.transform.SetParent(pieceObj.transform.parent); newPieceObj.SetActive(true); var trans = newPieceObj.transform; var endPosition = pieceObj.transform.localPosition; trans.localScale = startScale; trans.rotation = Quaternion.Euler(startRotation); trans.localPosition = startPostion; var ani = newPieceObj.gameObject.GetComponentInChildren(); if (ani) ani.Play(); trans.DOLocalMove(endPosition, time).SetEase(firstCurve); trans.DOLocalRotate(Vector3.zero, time).SetEase(firstCurve); await trans.DOScale(Vector3.one, time).SetEase(firstCurve).AsyncWaitForCompletion(); positonEndCallback?.Invoke(); await Awaiters.Seconds(delayDestroyTime); if (pieceObj) pieceObj?.SetActive(true); Destroy(newPieceObj); if (!isLastPiece) return; await GContext.container.Resolve().SetImageSprite(photo, _name); photo?.gameObject.SetActive(true); puzzle_completed?.Play(nameof(puzzle_completed)); await Awaiters.Seconds(puzzle_completed[nameof(puzzle_completed)].length); } } }