Files
back_cantanBuilding/Assets/Scripts/UI/PartnerGather/Mining/EventPartnerDrawMiningPanel.cs
2026-05-26 16:15:54 +08:00

1030 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using asap.core;
using cfg;
using DataCenter;
using game;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace UI.PartnerGather.Mining
{
/// <summary>
/// 事件合作伙伴抽奖挖矿面板控制器
/// 负责管理抽奖转盘UI、挖矿进度显示、场景控制器绑定等核心功能
///
/// 建议挂载在EventPartnerDrawMiningPanel UI预制体的根对象上
///
/// UI结构建议
/// EventPartnerDrawMiningPanel (挂载此脚本)
/// ├── root/
/// │ ├── turntable/Scroll_item (转盘滚动区域)
/// │ ├── btn_common_green/btn_green (抽奖按钮)
/// │ └── turnable/select (选中效果)
/// ├── btn_close (关闭按钮)
/// └── SettlementPanel/ (结算面板,可选)
/// ├── Rewards/ (奖励显示区域)
/// └── Trophy/ (奖杯显示区域)
///
/// 重要说明:
/// - 此脚本会自动查找和绑定采集场景控制器
/// - 需要正确设置转盘相关的UI引用
/// - 支持节点结算过场动画和奖杯显示系统
/// </summary>
public class EventPartnerDrawMiningPanel : MonoBehaviour
{
// 管理器
private EventPartnerGatherManager _eventPartnerGatherManager;
[Header("采集场景配置(运行时自动设置)")]
[SerializeField]
private EventPartnerMiningSceneController miningScene;
private bool _isProcessingResult = false;
// 更新点数即等级
[Header("=== 等级进度显示 ===")]
[Tooltip("等级节点控制器数组 - 每个节点对应一个挖矿阶段")]
public EventPartnerMiningLevelController[] levels;
public float contentDeltaX = 24;
public Image bar;
private Transform _level;
private Transform _turntable; // 转盘
private PanelScroll _scrollList; // 滚动列表
private Transform _select; // 选中效果
private Transform _priceItem; // 列表滚动中的数据
// 按钮
private Button _btnClose;
private Button _btnSpin;
private ScrollRect _scrollRect;
private RectTransform _viewport;
private RectTransform _content;
private RectTransform _itemTemplate;
// 记录当前的Item
private readonly List<EventPartnerSpinItemView> _spinItemViews = new();
// private readonly List<RectTransform> _rects = new List<RectTransform>();
private readonly List<int> _dataIndexMap = new List<int>();
[Header("结算过场配置")]
public Transform settlementPanel; // 结算面板
public Transform trophyDisplay; // 奖杯显示区域
public Transform nodeCompletionEffect; // 节点完成特效
public AudioClip settlementSound; // 结算音效
public AudioClip trophySound; // 奖杯音效
private bool _isShowingSettlement = false;
// 当前点数列表
private List<EventPartnerSpinPoint> _spinPointDatas;
// 0,1,2 停靠在第二个格子
private readonly int _starGrid = 2;
private int _dataCount;
private int _poolSize;
private float _itemWidth;
private bool _animating;
private float _autoScrollSpeed = 60f;
private bool _autoScroll = false;
// 自动滚动累积位移(用于与步进动画叠加)
private float _autoScrollAccumulation = 0f;
private void Awake()
{
//
_eventPartnerGatherManager = GContext.container.Resolve<EventPartnerGatherManager>();
//
_btnSpin = transform.Find("root/btn_common_green/btn_green").GetComponent<Button>();
_btnClose = transform.Find("btn_close").GetComponent<Button>();
_scrollList = transform.Find("root/turntable/Scroll_item").GetComponent<PanelScroll>();
_priceItem = transform.Find("root/turntable/Scroll_item/Viewport/Content/item");
_select = transform.Find("root/turnable/select");
}
private void Start()
{
_btnSpin.onClick.AddListener(OnSpin);
_btnClose.onClick.AddListener(OnClickCloseBtn);
// 运行时自动查找并设置采集场景控制器
FindAndSetMiningScene();
_ = UpdateScrollList();
}
private void FindAndSetMiningScene()
{
if (miningScene == null)
{
// 在场景中查找EventPartnerMiningSceneController
miningScene = FindObjectOfType<EventPartnerMiningSceneController>();
if (miningScene == null)
{
Log("警告未找到EventPartnerMiningSceneController采集功能将不可用");
}
else
{
Log($"已自动设置采集场景控制器:{miningScene.name}");
// 验证关键组件是否存在
ValidateMiningSceneComponents();
}
}
}
/// <summary>
/// 验证采集场景的关键组件
/// </summary>
private void ValidateMiningSceneComponents()
{
if (miningScene == null) return;
if (miningScene.character == null)
{
Log("警告:采集场景缺少角色控制器组件");
}
if (miningScene.trainController == null)
{
Log("警告:采集场景缺少火车控制器组件");
}
if (miningScene.miningPoints == null)
{
Log("警告:采集场景缺少挖矿点管理器组件");
}
}
/// <summary>
/// 供外部代码设置采集场景控制器
/// </summary>
public void SetMiningScene(EventPartnerMiningSceneController sceneController)
{
miningScene = sceneController;
Log($"已设置采集场景控制器:{sceneController?.name ?? "null"}");
}
private void Update()
{
if (_autoScroll && _dataCount > 0 && _content)
{
AutoScroll(Time.deltaTime);
}
}
private async Task UpdateScrollList()
{
_scrollRect = _scrollList.GetComponent<ScrollRect>();
_viewport = _scrollRect.viewport;
_content = _priceItem.parent as RectTransform;
_itemTemplate = (RectTransform)_priceItem;
_spinPointDatas = _eventPartnerGatherManager.EventPartnerSpinPointList;
_dataCount = _spinPointDatas?.Count ?? 0;
if (_dataCount == 0) { if (_btnSpin) _btnSpin.interactable = false; return; }
_itemWidth = _itemTemplate.rect.width;
_poolSize = Mathf.CeilToInt(_viewport.rect.width / _itemWidth) + 4;
BuildItemPool();
_priceItem.gameObject.SetActive(false);
// await AlignToIndexAsync(0, 2, 0.1f);
await Task.CompletedTask;
}
private void BuildItemPool()
{
// _rects.Clear();
_spinItemViews.Clear();
_dataIndexMap.Clear();
for (int i = 0; i < _poolSize; i++)
{
var r = Instantiate(_itemTemplate, _content);
r.gameObject.SetActive(true);
// _rects.Add(r);
Log($"r -> {r.sizeDelta}");
var spinItemView = r.GetComponent<EventPartnerSpinItemView>();
_spinItemViews.Add(spinItemView);
int di = i % _dataCount;
_dataIndexMap.Add(di);
BindItem(spinItemView, di);
}
// _content.rec
var size = _content.sizeDelta;
var size2 = _content.rect.size;
Log($"size -> {size}, {size2}");
var num = Mathf.RoundToInt(size2.x / 235.02f);
Log($"num-> {num}");
_content.anchoredPosition = Vector2.zero;
_scrollRect.enabled = false;
}
private void BindItem(EventPartnerSpinItemView spinItemView, int dataIndex)
{
// var v = r.GetComponent<SpinItemView>();
// if (!v) v = r.gameObject.AddComponent<SpinItemView>();
// v.Bind(_data[dataIndex]);
spinItemView?.Bind(_spinPointDatas[dataIndex],dataIndex);
}
private int GetStartDataIndex()
{
var idx = Mathf.Clamp(_starGrid,0,+_spinItemViews.Count);
return _dataIndexMap[idx];
}
private int GetCenterDataIndex()
{
int idx = _spinItemViews.Count / 2;
return _dataIndexMap[idx];
}
private void UpdateSelectionVisual(int targetIdxId)
{
// var targetIdx = this.targetIdx;
for (int i = 0; i < _spinItemViews.Count; i++)
{
// _spinItemViews[i].SetSelected(i == 2);
_spinItemViews[i].UpdateSelected(targetIdxId);
}
}
public async Task AlignToIndexAsync(int targetIndex, int loops, float duration)
{
if (_animating) return;
if (_dataCount == 0) return;
_animating = true;
SetInteractable(false);
// 不再停用自动滚动
int current = GetStartDataIndex(); // 恢复使用起始索引
int delta = (targetIndex - current + _dataCount) % _dataCount;
int steps = loops * _dataCount + delta;
for (int i = 0; i < steps; i++)
{
await MoveStepRight(duration);
}
SetInteractable(true);
_animating = false;
}
private async Task MoveStepRight(float duration)
{
// 记录步进开始时的自动滚动累积位移
float startAutoScroll = _autoScrollAccumulation;
float stepOffset = 0f; // 步进相对偏移
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.0001f, duration);
stepOffset = -_itemWidth * Mathf.SmoothStep(0f, 1f, t);
// 使用统一位置更新方法,传入步进偏移
UpdateContentPosition(stepOffset);
await Awaiters.NextFrame;
}
// 步进完成,执行标准化并调整自动滚动累积
_autoScrollAccumulation = (_autoScrollAccumulation + _itemWidth) % _itemWidth;
NormalizeAfterStepRight();
}
private void NormalizeAfterStepRight()
{
// 统一锚点驱动:只调整数据映射,不直接修改位置
// 位置由AutoScroll或步进动画统一控制
var first = _spinItemViews[0];
_spinItemViews.RemoveAt(0);
_spinItemViews.Add(first);
first.transform.SetSiblingIndex(_content.childCount - 1);
int lastData = _dataIndexMap[^1];
int ni = (lastData + 1) % _dataCount;
_dataIndexMap.RemoveAt(0);
_dataIndexMap.Add(ni);
BindItem(first, ni);
// 重置content位置到标准位置避免累积误差
if (!_animating)
{
_content.anchoredPosition = new Vector2(-_autoScrollAccumulation, _content.anchoredPosition.y);
}
}
private void UpdateContentPosition(float additionalOffset = 0f)
{
// 统一位置计算:基准位置 + 自动滚动累积 + 额外偏移
float finalX = -_autoScrollAccumulation + additionalOffset;
_content.anchoredPosition = new Vector2(finalX, _content.anchoredPosition.y);
}
private void AutoScroll(float dt)
{
_autoScrollAccumulation += _autoScrollSpeed * dt;
// 应用累积的自动滚动位移
while (_autoScrollAccumulation >= _itemWidth)
{
_autoScrollAccumulation -= _itemWidth;
NormalizeAfterStepRight();
}
// 使用统一位置更新方法
UpdateContentPosition();
}
public EventPartnerSpinPoint GetSelectedData()
{
return _dataCount == 0 ? null : _spinPointDatas[_dataIndexMap[_spinItemViews.Count / 2]];
}
private void ClearSelection()
{
foreach (var elem in _spinItemViews)
{
// var itemView = elem.GetComponent<SpinItemView>();
elem.SetSelected(false);
}
}
private async Task SpinToAsync(EventPartnerSpinPoint target, int loops, float fast, float slow)
{
if (_animating || target == null || _dataCount == 0) return;
var dataTargetIndex = _spinPointDatas.IndexOf(target);
if (dataTargetIndex < 0)
dataTargetIndex = 0;
_animating = true;
SetInteractable(false);
// 不再停用自动滚动,允许持续运行
ClearSelection();
var targetId = target.ID;
var current = GetStartDataIndex(); // 恢复使用起始索引(设计的中心位置)
int delta = (dataTargetIndex - current + _dataCount) % _dataCount;
int steps = loops * _dataCount + delta;
int accel = Mathf.Min(steps / 4, 6);
int decel = Mathf.Min(steps / 4, 6);
int steady = Mathf.Max(0, steps - accel - decel);
Log($"SpinToAsync -> current -> {current} targetIndex:{dataTargetIndex} delta: {delta}" );
for (int i = 0; i < accel; i++)
{
var d = Mathf.Lerp(fast, slow, (i + 1f) / accel);
await MoveStepRight(d);
}
for (int i = 0; i < steady; i++)
{
await MoveStepRight(slow);
}
for (int i = 0; i < decel; i++)
{
float d = Mathf.Lerp(slow, fast, (i + 1f) / decel);
await MoveStepRight(d);
}
UpdateSelectionVisual(targetId);
// 精确校正到中心位置
await AlignToCenterAsync();
// 抽中奖品后暂停自动滚动2秒然后重新开始
EnableAutoScroll(false);
await Task.Delay(2000);
EnableAutoScroll(true);
SetInteractable(true);
_animating = false;
}
private async Task AlignToCenterAsync()
{
// 添加明显的回中心动画效果
float currentX = _content.anchoredPosition.x;
float targetX = -_autoScrollAccumulation;
// 如果已经很接近中心,就不需要动画
if (Mathf.Abs(currentX - targetX) < 1f)
{
UpdateContentPosition();
await Task.Delay(50);
return;
}
// 平滑回中心动画
float t = 0f;
float duration = 0.3f; // 回中心动画持续时间
while (t < 1f)
{
t += Time.deltaTime / duration;
float x = Mathf.Lerp(currentX, targetX, Mathf.SmoothStep(0f, 1f, t));
_content.anchoredPosition = new Vector2(x, _content.anchoredPosition.y);
await Awaiters.NextFrame;
}
// 确保最终位置精确
UpdateContentPosition();
}
public void SetInteractable(bool v)
{
_btnSpin.interactable = v;
_btnClose.interactable = v && !_animating;
}
public void EnableAutoScroll(bool on)
{
_autoScroll = on;
}
public void SetAutoScrollSpeed(float s)
{
_autoScrollSpeed = Mathf.Max(0f, s);
}
public void ResumeAutoScroll()
{
// 供后续逻辑调用,恢复自动滚动
EnableAutoScroll(true);
}
private void OnDestroy()
{
_btnClose.onClick.RemoveAllListeners();
_btnSpin.onClick.RemoveAllListeners();
}
public void SetPoints(int points)
{
Log($"SetPoints ->{points}");
}
private void UpdateLevel(int level)
{
if (levels == null || levels.Length == 0) return;
level = Mathf.Clamp(level, 0, levels.Length);
for (int i = 0; i < levels.Length; ++i)
{
if (i < level) levels[i].UpdateStatus(LevelStatus.Done);
else if (i == level) levels[i].UpdateStatus(LevelStatus.Current);
else levels[i].UpdateStatus(LevelStatus.Normal);
}
}
public void SetMiningProgress(int progress)
{
Log($"SetMiningProgress {progress}");
var stage = _eventPartnerGatherManager.EventPartnerMain2Data?.StagePoint;
int completed = 0;
if (stage != null && stage.Count > 0)
{
int sum = 0;
for (int i = 0; i < stage.Count; i++)
{
sum += stage[i];
if (progress >= sum) completed++; else break;
}
}
UpdateLevel(Mathf.Min(completed, levels?.Length ?? 0));
}
public void SetTrainProgress(int cur, int max)
{
Log($"SetTrainProgress {cur} {max}");
// if (trainSlider != null)
// {
// trainSlider.minValue = 0;
// trainSlider.maxValue = max;
// trainSlider.value = cur;
// }
// if (txtTrainNode != null) txtTrainNode.text = $"{cur}/{max}";
}
public async void OnSpin()
{
var spinPoint = _eventPartnerGatherManager.GetSpinPointElem();
if (spinPoint == null) return;
Log($"OnSpin -> {spinPoint.ID} {spinPoint.SpinPointParam.json}");
// if (true)
// {
// await miningScene.StartMiningSequence(50);
// }
await SpinToAsync(spinPoint, 1, 0.05f, 0.12f);
//
// // 直接处理采集流程整合了GameController的功能
await OnSpinComplete(spinPoint);
//
// // 检查是否需要触发结算
CheckForNodeCompletion();
}
private async Task OnSpinComplete(EventPartnerSpinPoint spinResult)
{
if (_isProcessingResult || spinResult == null) return;
_isProcessingResult = true;
try
{
// 解析抽奖结果
var points = _eventPartnerGatherManager.ResolveSpinAndGetPoints(spinResult);
// 显示积分飘字
await ShowPointsFloatingText(points);
// 开始采集流程
if (miningScene != null)
{
await miningScene.StartMiningSequence(points);
}
// 更新积分和进度
if (points > 0)
{
_eventPartnerGatherManager.AddPoints(points);
UpdateProgressUI();
}
}
finally
{
_isProcessingResult = false;
}
}
private async Task ShowPointsFloatingText(int points)
{
// 在人物头顶显示积分飘字
if (miningScene?.character != null)
{
var floatingText = CreateFloatingText($"+{points}", miningScene.character.transform.position);
await AnimateFloatingText(floatingText);
}
}
private GameObject CreateFloatingText(string text, Vector3 worldPosition)
{
// 创建飘字UI
GameObject textObj = new GameObject("FloatingText");
textObj.transform.position = worldPosition + Vector3.up * 2f;
// 添加TextMesh组件
var textMesh = textObj.AddComponent<TextMesh>();
textMesh.text = text;
textMesh.fontSize = 20;
textMesh.color = Color.yellow;
textMesh.anchor = TextAnchor.MiddleCenter;
return textObj;
}
private async Task AnimateFloatingText(GameObject textObj)
{
if (textObj == null) return;
Vector3 startPos = textObj.transform.position;
Vector3 endPos = startPos + Vector3.up * 1.5f;
float duration = 1.5f;
float t = 0f;
var textMesh = textObj.GetComponent<TextMesh>();
Color startColor = textMesh.color;
while (t < 1f)
{
t += Time.deltaTime / duration;
// 位置动画
textObj.transform.position = Vector3.Lerp(startPos, endPos, t);
// 透明度动画
if (textMesh != null)
{
Color color = startColor;
color.a = Mathf.Lerp(1f, 0f, t);
textMesh.color = color;
}
await Awaiters.NextFrame;
}
DestroyImmediate(textObj);
}
private void UpdateProgressUI()
{
// 更新进度显示UI - 直接调用现有的UI更新方法
var currentMiningProgress = _eventPartnerGatherManager.GatherData?.CurrentMiningProgress ?? 0;
// 使用现有的SetMiningProgress方法更新进度显示
SetMiningProgress(currentMiningProgress);
// 检查是否需要触发节点结算
CheckForNodeCompletion();
}
public void OnClickCloseBtn()
{
GContext.Publish(new UnloadActToNextAct());
}
#region
private void CheckForNodeCompletion()
{
if (_eventPartnerGatherManager?.GatherData == null) return;
var trainProgress = _eventPartnerGatherManager.GatherData.TrainProgress;
var maxNodes = _eventPartnerGatherManager.MaxTrainNodes;
// 检查是否达到节点完成条件
if (trainProgress >= maxNodes && !_isShowingSettlement)
{
_ = ShowNodeCompletionSequence();
}
}
public async Task ShowNodeCompletionSequence()
{
if (_isShowingSettlement) return;
_isShowingSettlement = true;
try
{
Log("开始节点结算过场动画");
// 1. 禁用交互
SetInteractable(false);
EnableAutoScroll(false);
// 2. 显示节点完成特效
await ShowNodeCompletionEffect();
// 3. 计算奖励并显示结算面板
var rewards = CalculateNodeRewards();
await ShowSettlementPanel(rewards);
// 4. 显示奖杯(如果获得)
var trophy = GetTrophyForCompletion();
if (trophy != null)
{
await ShowTrophySequence(trophy);
}
// 5. 等待用户确认
await WaitForSettlementConfirmation();
// 6. 重置场景准备下一轮
await ResetForNextRound();
}
finally
{
_isShowingSettlement = false;
SetInteractable(true);
EnableAutoScroll(true);
}
}
private async Task ShowNodeCompletionEffect()
{
if (nodeCompletionEffect == null) return;
// 播放完成音效
if (settlementSound != null)
{
AudioSource.PlayClipAtPoint(settlementSound, Camera.main.transform.position);
}
// 显示完成特效
nodeCompletionEffect.gameObject.SetActive(true);
// 特效动画
var scale = nodeCompletionEffect.localScale;
nodeCompletionEffect.localScale = Vector3.zero;
float duration = 1f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / duration;
float ease = Mathf.SmoothStep(0f, 1f, t);
nodeCompletionEffect.localScale = Vector3.Lerp(Vector3.zero, scale, ease);
await Awaiters.NextFrame;
}
await Task.Delay(1000); // 特效持续时间
nodeCompletionEffect.gameObject.SetActive(false);
}
private NodeRewards CalculateNodeRewards()
{
var gatherData = _eventPartnerGatherManager?.GatherData;
if (gatherData == null) return new NodeRewards();
return new NodeRewards
{
Points = gatherData.CurrentPoints,
Coins = gatherData.CurrentPoints * 10, // 积分转币率
Items = GetBonusItems(),
Experience = 100 // 固定经验奖励
};
}
private List<RewardItem> GetBonusItems()
{
// 根据完成度给予奖励物品
var items = new List<RewardItem>();
var trainProgress = _eventPartnerGatherManager?.GatherData?.TrainProgress ?? 0;
// 基础奖励
items.Add(new RewardItem { ItemId = 1001, Count = 5, Name = "挖矿工具" });
// 根据进度给予额外奖励
if (trainProgress >= 50)
{
items.Add(new RewardItem { ItemId = 1002, Count = 3, Name = "稀有矿石" });
}
if (trainProgress >= 100)
{
items.Add(new RewardItem { ItemId = 1003, Count = 1, Name = "传说装备" });
}
return items;
}
private async Task ShowSettlementPanel(NodeRewards rewards)
{
if (settlementPanel == null) return;
Log($"显示结算面板,奖励:{rewards.Points}积分, {rewards.Coins}金币");
settlementPanel.gameObject.SetActive(true);
// 更新结算面板数据
UpdateSettlementPanelData(rewards);
// 面板进入动画
var canvasGroup = settlementPanel.GetComponent<CanvasGroup>();
if (canvasGroup == null) canvasGroup = settlementPanel.gameObject.AddComponent<CanvasGroup>();
canvasGroup.alpha = 0f;
canvasGroup.interactable = false;
float duration = 0.5f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / duration;
canvasGroup.alpha = Mathf.SmoothStep(0f, 1f, t);
await Awaiters.NextFrame;
}
canvasGroup.interactable = true;
}
private void UpdateSettlementPanelData(NodeRewards rewards)
{
// 更新结算面板中的奖励显示
var pointsText = settlementPanel.Find("Rewards/Points/Text")?.GetComponent<TMP_Text>();
var coinsText = settlementPanel.Find("Rewards/Coins/Text")?.GetComponent<TMP_Text>();
var expText = settlementPanel.Find("Rewards/Experience/Text")?.GetComponent<TMP_Text>();
if (pointsText) pointsText.text = rewards.Points.ToString();
if (coinsText) coinsText.text = rewards.Coins.ToString();
if (expText) expText.text = rewards.Experience.ToString();
// 更新物品奖励列表
var itemsList = settlementPanel.Find("Rewards/Items");
if (itemsList != null)
{
// 清理现有物品显示
for (int i = itemsList.childCount - 1; i >= 0; i--)
{
DestroyImmediate(itemsList.GetChild(i).gameObject);
}
// 创建物品显示
foreach (var item in rewards.Items)
{
CreateRewardItemDisplay(item, itemsList);
}
}
}
private void CreateRewardItemDisplay(RewardItem item, Transform parent)
{
GameObject itemObj = new GameObject($"Item_{item.ItemId}");
itemObj.transform.SetParent(parent);
var text = itemObj.AddComponent<TMP_Text>();
text.text = $"{item.Name} x{item.Count}";
text.fontSize = 14;
text.color = Color.white;
}
private TrophyData GetTrophyForCompletion()
{
var trainProgress = _eventPartnerGatherManager?.GatherData?.TrainProgress ?? 0;
// 根据完成度决定奖杯等级
if (trainProgress >= 100)
{
return new TrophyData
{
Id = 3001,
Name = "挖矿大师",
Description = "完美完成挖矿任务",
Rarity = TrophyRarity.Legendary
};
}
else if (trainProgress >= 80)
{
return new TrophyData
{
Id = 3002,
Name = "挖矿专家",
Description = "出色完成挖矿任务",
Rarity = TrophyRarity.Epic
};
}
else if (trainProgress >= 50)
{
return new TrophyData
{
Id = 3003,
Name = "挖矿能手",
Description = "良好完成挖矿任务",
Rarity = TrophyRarity.Rare
};
}
return null; // 未达到奖杯要求
}
private async Task ShowTrophySequence(TrophyData trophy)
{
if (trophyDisplay == null || trophy == null) return;
Log($"获得奖杯:{trophy.Name} - {trophy.Description}");
// 播放奖杯音效
if (trophySound != null)
{
AudioSource.PlayClipAtPoint(trophySound, Camera.main.transform.position);
}
trophyDisplay.gameObject.SetActive(true);
// 更新奖杯显示信息
UpdateTrophyDisplay(trophy);
// 奖杯出现动画
await AnimateTrophyAppearance();
// 显示3秒
await Task.Delay(3000);
}
private void UpdateTrophyDisplay(TrophyData trophy)
{
var nameText = trophyDisplay.Find("Trophy/Name")?.GetComponent<TMP_Text>();
var descText = trophyDisplay.Find("Trophy/Description")?.GetComponent<TMP_Text>();
var rarityText = trophyDisplay.Find("Trophy/Rarity")?.GetComponent<TMP_Text>();
if (nameText) nameText.text = trophy.Name;
if (descText) descText.text = trophy.Description;
if (rarityText) rarityText.text = trophy.Rarity.ToString();
// 根据稀有度设置颜色
Color rarityColor = trophy.Rarity switch
{
TrophyRarity.Legendary => Color.yellow,
TrophyRarity.Epic => Color.magenta,
TrophyRarity.Rare => Color.blue,
_ => Color.white
};
if (rarityText) rarityText.color = rarityColor;
}
private async Task AnimateTrophyAppearance()
{
var trophyIcon = trophyDisplay.Find("Trophy/Icon");
if (trophyIcon == null) return;
// 缩放动画
Vector3 originalScale = trophyIcon.localScale;
trophyIcon.localScale = Vector3.zero;
float duration = 1f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / duration;
float ease = Mathf.SmoothStep(0f, 1f, t);
// 弹性效果
float scale = ease * (1f + 0.2f * Mathf.Sin(ease * Mathf.PI * 4f));
trophyIcon.localScale = originalScale * scale;
await Awaiters.NextFrame;
}
trophyIcon.localScale = originalScale;
}
private async Task WaitForSettlementConfirmation()
{
// 等待用户点击确认按钮
var confirmBtn = settlementPanel?.Find("Buttons/ConfirmBtn")?.GetComponent<Button>();
if (confirmBtn == null)
{
// 如果没有确认按钮等待3秒后自动关闭
await Task.Delay(3000);
return;
}
bool confirmed = false;
confirmBtn.onClick.AddListener(() => confirmed = true);
// 等待用户确认
while (!confirmed)
{
await Awaiters.NextFrame;
}
confirmBtn.onClick.RemoveAllListeners();
}
private async Task ResetForNextRound()
{
Log("准备下一轮挖矿");
// 隐藏结算相关UI
if (settlementPanel) settlementPanel.gameObject.SetActive(false);
if (trophyDisplay) trophyDisplay.gameObject.SetActive(false);
// 重置采集场景
if (miningScene != null)
{
miningScene.ResetScene();
}
// 重置管理器数据(如果需要)
// _eventPartnerGatherManager?.ResetForNextRound();
await Task.Delay(500); // 短暂延迟确保重置完成
}
#endregion
#region
[System.Serializable]
public class NodeRewards
{
public int Points;
public int Coins;
public int Experience;
public List<RewardItem> Items = new List<RewardItem>();
}
[System.Serializable]
public class RewardItem
{
public int ItemId;
public string Name;
public int Count;
}
[System.Serializable]
public class TrophyData
{
public int Id;
public string Name;
public string Description;
public TrophyRarity Rarity;
}
public enum TrophyRarity
{
Common,
Rare,
Epic,
Legendary
}
#endregion
private static void Log(object t)
{
Debug.Log($"<color=cyan>EventPartnerDrawMiningPanel -> {t} </color>");
}
}
}