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

187 lines
5.5 KiB
C#

using DG.Tweening;
using GameCore;
using Spine.Unity;
using TMPro;
using UnityEngine;
public class MiniBattlePassSecondPanel : MiniBattlePassPanel
{
TMP_Text text_num1;
/// <summary>角色根节点,须在 Content 下;实例化 item 后会 <see cref="OnAfterMiniBattlePassItemsInstantiated"/> 设为同级最末以便后渲染盖在列表上。若受 VerticalLayoutGroup 排布影响,请给该节点加 LayoutElement 并勾选 Ignore Layout。</summary>
protected Transform spineRoot;
protected SkeletonGraphic spine;
RewardItemNew reward;
protected override int NormalizedPosition => 0;
protected override int showCount => 5;
/// <summary>
/// 与 <see cref="MiniBattlePassSecondPanel"/> 原 Spine 对齐规则一致:非最后一档时视觉行 = 数据下标 + 1。
/// </summary>
protected int GetDisplayRowIndexForDataIndex(int dataIndex)
{
if (miniBPItemDatas == null || miniBPItemDatas.Count == 0)
{
return 0;
}
int row = dataIndex;
if (row < miniBPItemDatas.Count - 1)
{
row++;
}
return row;
}
protected void SetCharacterRootY(int displayRowIndex)
{
if (spineRoot == null)
{
return;
}
spineRoot.localPosition = new Vector3(spineRoot.localPosition.x, displayRowIndex * itemHeight, 0);
}
protected virtual void PlayCharacterIdleAnimation()
{
if (spine != null)
{
spine.AnimationState.SetAnimation(0, "swimming_idle", true);
}
}
protected virtual void PlayCharacterMoveAnimation()
{
if (spine != null)
{
spine.AnimationState.SetAnimation(0, "swimming_move", true);
}
}
protected virtual void OnCharacterScrollArrived()
{
PlayCharacterIdleAnimation();
}
/// <summary>
/// 开始「追进度」滚动:列表滚动与角色根节点 Y 同步。视频版可重写以在开始前插入转身等。
/// </summary>
protected virtual void StartCharacterScrollToReward(int startRow, int endRow, float endScrollPos, float duration)
{
if (spineRoot == null || scrollRect == null)
{
return;
}
PlayCharacterMoveAnimation();
scrollRect.DOVerticalNormalizedPos(endScrollPos, duration).SetEase(Ease.Linear);
spineRoot.DOLocalMoveY(endRow * itemHeight, duration).OnComplete(OnCharacterScrollArrived);
}
protected override void Awake()
{
base.Awake();
reward = transform.Find("root/total_prize/bg/reward").GetComponent<RewardItemNew>();
spineRoot = transform.Find("root/ScrollView/Viewport/Content/spineRoot");
if (spineRoot != null)
{
var spineTransform = spineRoot.Find("spine");
if (spineTransform != null)
{
spine = spineTransform.GetComponent<SkeletonGraphic>();
}
}
text_num1 = transform.Find("root/total_prize/reward/text_num").GetComponent<TMP_Text>();
}
protected override void OnAfterMiniBattlePassItemsInstantiated()
{
base.OnAfterMiniBattlePassItemsInstantiated();
if (spineRoot == null || content == null || spineRoot.parent != content)
{
return;
}
spineRoot.SetAsLastSibling();
}
protected override void Start()
{
if (miniBP.ItemShow[1] == 1001)
{
int showCount = 0;
var miniBPItemDatas = miniBP.miniBPItemDatas;
ItemData itemData;
for (int i = 0; i < miniBPItemDatas.Count; i++)
{
itemData = miniBPItemDatas[i].freeReward;
if (itemData != null && itemData.id == 1001)
{
showCount += itemData.count;
}
itemData = miniBPItemDatas[i].grandReward;
if (itemData != null && itemData.id == 1001)
{
showCount += itemData.count;
}
}
miniBP.ItemCountShow[1] = showCount;
}
base.Start();
reward.SetData(miniBP.ItemShow[0], $"x{ConvertTools.GetNumberString(miniBP.ItemCountShow[0])}", true);
text_num1.text = $"x{ConvertTools.GetNumberString(miniBP.ItemCountShow[1])}";
}
protected override void JumpToIndex()
{
if (spineRoot == null)
{
return;
}
int index = miniBP.Data.showIndex;
float startPos = ((index - 2) * 1f / (miniBPItemDatas.Count - showCount));
if (startPos > 1f)
{
startPos = 1f;
}
if (startPos < 0f)
{
startPos = 0f;
}
scrollRect.verticalNormalizedPosition = startPos;
int startRow = GetDisplayRowIndexForDataIndex(miniBP.Data.showIndex);
SetCharacterRootY(startRow);
if (miniBP.rewardIndex > index)
{
miniBP.SetOldLevel();
float endPos = ((miniBP.rewardIndex - 2) * 1f / (miniBPItemDatas.Count - showCount));
if (endPos > 1f)
{
endPos = 1f;
}
if (endPos < 0f)
{
endPos = 0f;
}
const float scrollDuration = 1f;
int endRow = GetDisplayRowIndexForDataIndex(miniBP.rewardIndex);
StartCharacterScrollToReward(startRow, endRow, endPos, scrollDuration);
}
else
{
PlayCharacterIdleAnimation();
}
}
}