200 lines
7.2 KiB
C#
200 lines
7.2 KiB
C#
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<Image>(true);
|
||
pieceObjs = pieceParentObj.FindGameObjects(new string[] { "piece1", "piece2", "piece3", "piece4", "piece5", "piece6" });
|
||
photo = this.gameObject.FindChildGameObject(nameof(photo)).GetComponent<Image>();
|
||
puzzle_completed = this.GetComponent<Animation>();
|
||
InitUI();
|
||
}
|
||
|
||
private void InitUI()
|
||
{
|
||
photo.gameObject.SetActive(false);
|
||
foreach (var piece in pieceObjs)
|
||
{
|
||
piece.gameObject.SetActive(false);
|
||
piece.FindChildGameObject(fxName)?.SetActive(false);
|
||
}
|
||
}
|
||
|
||
private List<int> _unlockPieces;
|
||
private string _name;
|
||
|
||
public void SetData(List<int> unlockPieces, string pictureName, bool isDelayShow)
|
||
{
|
||
if (_unlockPieces == null)
|
||
_unlockPieces = new List<int>();
|
||
_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<IUIService>().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<IUIService>().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<IUIService>()
|
||
.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<Animation>();
|
||
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<IUIService>().SetImageSprite(photo, _name);
|
||
photo?.gameObject.SetActive(true);
|
||
puzzle_completed?.Play(nameof(puzzle_completed));
|
||
await Awaiters.Seconds(puzzle_completed[nameof(puzzle_completed)].length);
|
||
}
|
||
}
|
||
} |