Files
ft/Client/Assets/Scripts/UI/JigsawPuzzle/JigsawPuzzleSlotsComponent.cs
2026-06-29 21:18:33 +08:00

238 lines
9.4 KiB
C#

using System;
using Assets.Scripts.UI.AnimationSimulator;
using cfg;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using EnhancedUI.EnhancedScroller;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using asap.core;
using Coffee.UIExtensions;
using GameCore;
using UnityEngine;
using static EnhancedUI.EnhancedScroller.EnhancedScroller;
namespace Assets.Scripts.UI.JigsawPuzzle
{
public class JigsawPuzzleSlotsComponent : MonoBehaviour, IEnhancedScrollerDelegate
{
private JigsawPuzzleCell cellView;
private EnhancedScroller enhancedScroller;
private AnimationSimulatorComponent p_slot;
private GameObject fx_ui_jigsawpuzzlebuilding_spin_light;
private GameObject fx_ui_jigsawpuzzlebuilding_reward_selected;
[SerializeField, Tooltip("待机时卡带每转一圈花费的时间")]
private float idleTime = 20f;
public readonly float cellViewSize = 210f;
private List<EventJigsawPuzzleReward> _puzzleRewards;
private TweenerCore<Vector2, Vector2, VectorOptions> _doTween;
private float normalizeScale => enhancedScroller.Container.sizeDelta.x / 3;
public EnhancedScroller EnhancedScroller => enhancedScroller;
private void Awake()
{
cellView = this.transform.GetComponentInChildren<JigsawPuzzleCell>();
enhancedScroller = this.transform.GetComponentInChildren<EnhancedScroller>();
p_slot = this.transform.GetComponentInChildren<AnimationSimulatorComponent>();
fx_ui_jigsawpuzzlebuilding_spin_light = gameObject.FindChildGameObject(nameof(fx_ui_jigsawpuzzlebuilding_spin_light));
fx_ui_jigsawpuzzlebuilding_reward_selected = gameObject.FindChildGameObject(nameof(fx_ui_jigsawpuzzlebuilding_reward_selected));
// #if UNITY_EDITOR
// var gameObj = new GameObject("debugText");
// gameObj.transform.SetParent(cellView.transform, false);
// var text = gameObj.GetComponentOrAdd<TextMeshProUGUI>();
// text.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
// text.color = Color.white;
// text.alignment = TextAlignmentOptions.Center;
// #endif
InitUI();
}
private void OnDestroy()
{
_puzzleRewards?.Clear();
_puzzleRewards = null;
}
private void InitUI()
{
cellView.gameObject.SetActive(false);
fx_ui_jigsawpuzzlebuilding_reward_selected.SetActive(false);
fx_ui_jigsawpuzzlebuilding_spin_light.SetActive(false);
}
public void SetData(List<EventJigsawPuzzleReward> puzzleRewards)
{
_puzzleRewards = puzzleRewards;
enhancedScroller.Delegate = this;
enhancedScroller.ReloadData();
PlayIdleAni();
}
public void PlayIdleAni()
{
if(fx_ui_jigsawpuzzlebuilding_reward_selected)
fx_ui_jigsawpuzzlebuilding_reward_selected?.SetActive(false);
var time = Mathf.Abs(enhancedScroller.Container.anchoredPosition.x) / normalizeScale * idleTime;
_doTween?.Kill();
_doTween = enhancedScroller.Container.DOAnchorPosX(0, time)
.SetEase(Ease.Linear).OnComplete(() =>
{
_doTween = enhancedScroller.Container.DOAnchorPosX(0, idleTime)
.SetEase(Ease.Linear)
.SetLoops(100, LoopType.Restart);
});
}
public RectTransform GetDefaultCellView_Piece()
{
var piece = cellView.gameObject.FindChildGameObject("piece").transform;
if (piece == null) return cellView.RewardFlySource;
return (RectTransform)piece;
}
public RectTransform GetDefaultCellView_Item()
{
var itemNew = cellView.gameObject.GetComponentInChildren<RewardItemNew>();
return itemNew == null ? cellView.RewardFlySource : itemNew.icon.rectTransform;
}
public Vector3 GetTargetPosition(Item item)
{
var particleAttractorData = new ParticleAttractorData
{
Type = item.Type,
SubType = item.SubType,
Priority = -1,
IgnorePack = true
};
GContext.Publish(particleAttractorData);
if (particleAttractorData.uIParticleAttractorCenter != null)
return particleAttractorData.uIParticleAttractorCenter.transform.position;
Debug.LogWarning($"[ChainSlot] Type {item.Type} SubType {item.SubType} uIParticleAttractorCenter is null ,targetPos is null ");
return Vector3.zero;
}
public Vector3 GetPositonByDataIndex(int index)
{
var startCell = enhancedScroller.GetCellViewAtDataIndex(index);
if (startCell != null)
{
return startCell.transform.position;
}
return Vector3.zero;
}
#region slotsAni
public async Task SlotsAni(int random,CancellationToken cancellationToken)
{
_doTween?.Kill();
var particleSystems = fx_ui_jigsawpuzzlebuilding_spin_light.GetComponentsInChildren<ParticleSystem>();
foreach (var ps in particleSystems)
{
ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
ps.Clear();
ps.time = 0;
}
fx_ui_jigsawpuzzlebuilding_spin_light.SetActive(true);
foreach (var ps in particleSystems)
{
ps.Play();
ps.Simulate(0, true, true);
}
var rect = p_slot.GetComponent<RectTransform>();
var param = new AnimationSimulatorComponent.Parameter();
param.scale = normalizeScale;
param.startValue = enhancedScroller.ScrollPosition;
param.offsetDirection = RandomOffsetDirection(_puzzleRewards[random]);
param.updateCallback = (currentVelocity, currentValue)
=>
{
if (currentValue < 0)
currentValue = (currentValue % normalizeScale) + normalizeScale;
enhancedScroller.ScrollPosition = currentValue;
};
param.uniformCompletionStartCallBack = (currentValue)
=>
{
var postion = enhancedScroller.GetScrollPositionForDataIndex(random, CellViewPositionEnum.Before);
var offsetValue = (postion - rect.sizeDelta.x / 2 + cellViewSize / 2) % normalizeScale - normalizeScale;
float revertValue = currentValue < 0 ?
currentValue - normalizeScale + Mathf.Abs(currentValue % normalizeScale)
: 0;
var targetValue = revertValue + offsetValue;
return targetValue;
};
try
{
await p_slot.PlayEffect(param, cancellationToken);
}
catch (OperationCanceledException o)
{
//Debug.LogError($"OperationCanceledException {o}");
}
catch (Exception ex)
{
Debug.LogError(ex);
}
finally
{
// 只有在没有被取消的情况下才关闭粒子效果
// 如果被取消,说明新的 SlotsAni 已经接管,不应关闭
if (!cancellationToken.IsCancellationRequested)
{
fx_ui_jigsawpuzzlebuilding_reward_selected.SetActive(true);
fx_ui_jigsawpuzzlebuilding_spin_light.SetActive(false);
var particleSystemsLight = fx_ui_jigsawpuzzlebuilding_spin_light.GetComponentsInChildren<ParticleSystem>();
foreach (var ps in particleSystemsLight)
{
ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
ps.Clear();
ps.time = 0;
}
}
}
}
private bool RandomOffsetDirection(EventJigsawPuzzleReward reward)
{
var random = UnityEngine.Random.Range(1, 101);
return random <= reward.LeftWeight;
}
#endregion slotsAni
#region enhanced scroller
public int GetNumberOfCells(EnhancedScroller scroller)
{
return _puzzleRewards.Count;
}
public float GetCellViewSize(EnhancedScroller scroller, int DataIndex)
{
return cellViewSize;
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
var cell = scroller.GetCellView(cellView);
if (cell is not JigsawPuzzleCell puzzleCell) return null;
cell.gameObject.SetActive(true);
puzzleCell.SetData(_puzzleRewards[dataIndex]);
// #if UNITY_EDITOR
// var debugText = cell.gameObject.FindChildGameObject("debugText")?.GetComponent<TextMeshProUGUI>();
// if (debugText)
// debugText.text = $"Index:{reward.Quality} {reward.Index}";
// #endif
return cell;
}
#endregion enhanced scroller
}
}