Files
5.24BuYu/Assets/MyGame/aa/UI/Home/Sub/UIHome_BY_UISignViewPanel.cs
T
2026-10-19 19:02:29 +08:00

240 lines
8.9 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 Assets.MyGame.Scripts.Net;
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using Assets.MyGame.Scripts.Net.APIResponses;
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UIHome_BY_UISignViewPanel : SubUIBase
{
//text_CoinNums是转盘各个位置的详细值 他从GameManager的activityConfig里面读取signActivityConfig.days后端配置的个数和text_CoinNums的个数是对应的 这里赋值的时候需要加上其他的数据公式是 值+值*GameManager的gameConfig的vip的signInAdd签到加成
/*签到API已封装在APIRequestList.SignIn(GET)
响应为SignRewardResult:{day, gold, diamond, product}——day=本次签到天数(1~7),转盘直接按day停靠格子(不再金额反查)*/
//SLZPDieEvent这个脚本有之前写好的多层转盘的逻辑 签到这里只有单层 你可以直接看一下里面正确的
public List<Text> text_CoinNums;
public List<TextMeshProUGUI> text_CoinNums_TMP;
public TextMeshProUGUI tmp_VipJiaCheng; // 显示VIP签到加成百分比
public TextMeshProUGUI tmp_EndCoin; // 显示最终奖励金币数
public Button btn_ChouJiang;
public GameObject zhuanPan;
Dictionary<int, SignConfig> day_singConfig; // key=第几天(1~7)
[Header("转盘参数(参照SLZPDieEvent)")]
public int spinRounds = 5; // 到达目标前转的圈数
public float rotateDuration = 2f; // 旋转总时长
public float dir = -1f; // 旋转方向(-1逆时针,1顺时针)
private bool isSpinning;
public override void Awake()
{
base.Awake();
btn_ChouJiang.onClick.AddListener(OnChouJiangClick);
}
protected override void OnShow(object args = null)
{
base.OnShow(args);
OnChouJiangClick();
RefreshPanel();
}
private void RefreshPanel()
{
BuildDaySignConfig();
UpdateSlotTexts();
UpdateBtnState();
UpdateVipAddText();
}
/// <summary>显示VIP签到加成百分比(signInAdd 0.15 → +15%)</summary>
private void UpdateVipAddText()
{
if (tmp_VipJiaCheng == null) return;
double add = GetSignInAdd();
tmp_VipJiaCheng.text = $"+{add * 100:0}%";
}
/// <summary>从GameManager的activityConfig读取signActivityConfig.days,按day建立字典</summary>
private void BuildDaySignConfig()
{
day_singConfig = new Dictionary<int, SignConfig>();
var days = GameManager.Instance.activityConfig?.signActivityConfig?.days;
if (days == null) return;
foreach (var cfg in days)
{
if (cfg == null) continue;
day_singConfig[cfg.day] = cfg;
}
}
/// <summary>当前用户的VIP签到加成(gameConfig.vipLevelConfigs按用户vipLevel匹配signInAdd)</summary>
private double GetSignInAdd()
{
var vipConfigs = GameManager.Instance.gameConfig?.vipLevelConfigs;
if (vipConfigs == null || vipConfigs.Count == 0) return 0;
var user = GameManager.Instance.user;
if (user?.assets == null) return 0;
var vipCfg = vipConfigs.Find(v => v.level == user.assets.vipLevel);
return vipCfg?.signInAdd ?? 0;
}
/// <summary>转盘格子数量:UGUI Text列表有绑定就用它,否则用TMP列表</summary>
private int SlotCount()
{
if (text_CoinNums != null && text_CoinNums.Count > 0) return text_CoinNums.Count;
return text_CoinNums_TMP != null ? text_CoinNums_TMP.Count : 0;
}
/// <summary>给第index个转盘格子设置文本(兼容UGUI Text与TMP)</summary>
private void SetSlotText(int index, string value)
{
if (text_CoinNums != null && index < text_CoinNums.Count)
text_CoinNums[index].text = value;
else if (text_CoinNums_TMP != null && index < text_CoinNums_TMP.Count)
text_CoinNums_TMP[index].text = value;
}
/// <summary>转盘格子赋值:金币值+值*signInAdd(VIP签到加成),按day排序后与text_CoinNums一一对应</summary>
private void UpdateSlotTexts()
{
int slotCount = SlotCount();
if (day_singConfig == null || day_singConfig.Count == 0 || slotCount == 0) return;
var list = new List<SignConfig>(day_singConfig.Values);
list.Sort((a, b) => a.day - b.day);
double add = GetSignInAdd();
int count = Mathf.Min(list.Count, slotCount);
for (int i = 0; i < count; i++)
{
long gold = GetGiftGold(list[i]);
long showGold = gold + (long)Math.Round(gold * add);
SetSlotText(i, FormatGold(showGold));
}
}
/// <summary>取单日配置中的金币奖励数(giftList 中 type=1 金币项;无金币项返回0)</summary>
private static long GetGiftGold(SignConfig cfg)
{
if (cfg?.giftList == null) return 0;
var goldGift = cfg.giftList.Find(g => g != null && g.type == 1);
return goldGift != null ? goldGift.count : 0;
}
/// <summary>今日是否已签到</summary>
private bool IsSignedToday()
{
var sign = GameManager.Instance.user?.sign;
return sign != null && sign.isSign;
}
private void UpdateBtnState()
{
btn_ChouJiang.interactable = !isSpinning && !IsSignedToday();
}
private void OnChouJiangClick()
{
if (isSpinning) return;
btn_ChouJiang.interactable = false;
// SignIn 返回 SignRewardResult:day=本次签到天数,gold/diamond/product=本次奖励(服务端已含VIP加成)
APIRequestList.SignIn(res =>
{
if (res == null)
{
OnSignInDone(0);
return;
}
int slot = SlotIndexByDay(res.day);
if (slot < 0)
{
// day 匹配不到格子:不转转盘直接提示,避免停错位置
Debug.LogWarning($"[签到] 第{res.day}天在签到配置里匹配不到对应格子");
OnSignInDone(res.gold);
return;
}
Debug.Log($"[签到] 第{res.day}天奖励{res.gold}金币 → 转盘格子{slot}");
RotateToSlot(slot, () => OnSignInDone(res.gold));
});
}
/// <summary>签到完成:提示奖励并刷新用户数据</summary>
private void OnSignInDone(long reward)
{
UIManager.Instance.ShowBoardError($"签到成功,获得{FormatGold(reward)}金币");
if (tmp_EndCoin != null)
tmp_EndCoin.text = FormatGold(reward);
APIRequestList.GetUser(user =>
{
GameManager.Instance.UpdataUserData(user);
UpdateBtnState();
});
}
/// <summary>按签到天数定位转盘格子:days按day升序后的下标;匹配不到返回-1</summary>
private int SlotIndexByDay(int day)
{
if (day_singConfig == null || day_singConfig.Count == 0 || SlotCount() == 0) return -1;
var list = new List<SignConfig>(day_singConfig.Values);
list.Sort((a, b) => a.day - b.day);
int count = Mathf.Min(list.Count, SlotCount());
for (int i = 0; i < count; i++)
{
if (list[i].day == day) return i;
}
return -1;
}
/// <summary>单层转盘旋转停靠(参照SLZPDieEvent:LocalAxisAdd增量旋转+OutCubic缓动+完成强制校正)</summary>
private void RotateToSlot(int slot, Action onComplete)
{
isSpinning = true;
int cellCount = Mathf.Max(SlotCount(), 1);
float targetAngle = slot * (360f / cellCount);
float curr = zhuanPan.transform.localRotation.eulerAngles.z;
float deltaToTarget = AngleDiff(curr, targetAngle, dir);
float totalDelta = dir * spinRounds * 360f + deltaToTarget;
Tween tween = zhuanPan.transform.DOLocalRotate(new Vector3(0, 0, totalDelta), rotateDuration, RotateMode.LocalAxisAdd);
tween.SetEase(Ease.OutCubic);
tween.OnComplete(() =>
{
// 强制校正到精确目标角度,消除浮点误差
zhuanPan.transform.localRotation = Quaternion.Euler(0, 0, targetAngle);
isSpinning = false;
onComplete?.Invoke();
});
}
/// <summary>从curr到target的同向角度差(参照SLZPDieEvent.AngleDiff)</summary>
private float AngleDiff(float curr, float target, float dir)
{
float diff = (target - curr) % 360f;
if (diff < 0) diff += 360f;
if (dir < 0 && diff > 0) diff -= 360f;
return diff;
}
/// <summary>金币数值格式化(万/亿单位)</summary>
private static string FormatGold(long gold)
{
if (gold >= 100000000) // 亿
return $"{(gold / 100000000f):F1}亿";
if (gold >= 10000) // 万
return $"{(gold / 10000f):F1}万";
return gold.ToString("N0");
}
}