using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Collections; using UnityEngine.Networking; using Newtonsoft.Json.Linq; namespace LocalRank { [RequireComponent(typeof(RankUpAnimator))] public class RankManager : MonoBehaviour { public Transform content; // Content节点 public GameObject itemPrefab; // 排行榜Item预制体 public InputField inputField; private RankUpAnimator rankUpAnimator; // RankUpAnimator脚本引用 private List rankDataList = new List(); private int userId; private void Awake() { rankUpAnimator = GetComponent(); if (rankUpAnimator == null) { Debug.LogError("RankUpAnimator 组件未找到!"); } if (inputField != null) { inputField.onEndEdit.AddListener(InputScore); } } private void Start() { rankUpAnimator.onAnimationStart = () => { HideAllRankIcons(); // 滚动前隐藏图标和名次数字 }; rankUpAnimator.onAnimationComplete = () => { RefreshRankIcons(); // 滚动后恢复图标或数字 }; StartSync(); CreateUserId(); } // 你可以在这里定义游戏 ID 或者动态获取 private int gameId = 1; /// /// 创建本地排行榜,进入场景时候直接创建。比如游戏场景 /// 不同的游戏ID对应不同的排行榜 /// private void StartSync(int CurrentGameId = 1) { gameId = CurrentGameId; // 判断是否已创建表 if (RankService.IsTableExists(gameId)) { Debug.Log($"rank_game_{gameId} 表已存在!"); } else { Debug.Log($"rank_game_{gameId} 表不存在,正在创建..."); RankService.CreateTableIfNotExists(gameId); } } /// /// 创建一个userId,每个userId都是一条排行榜数据。 /// 后续上传分数时候使用 /// private void CreateUserId() { //获取一个时间戳值 userId = RankService.GenerateLocalUserId(); } /// /// 通过Input End 上传分数 /// /// void InputScore(string score) { int parsedScore; if (!int.TryParse(score, out parsedScore)) { Debug.LogError("输入的分数无效!"); return; } RankService.UploadScore(gameId, userId, "Player_" + userId, "", parsedScore); Debug.Log($"InputScore rank_game_{gameId} 上传 Id:{userId}分数!"); GetLocalRankList(); } /// /// 上传一个随机分数 /// public void UploadScore() { int seed = 0; var random = seed == 0 ? new System.Random() : new System.Random(seed); int score = random.Next(0, 1000); // 0~999 分之间 RankService.UploadScore(gameId, userId, "Player_" + userId, "", score); Debug.Log($"UploadScore rank_game_{gameId} 上传 Id:{userId}分数!"); GetLocalRankList(); } /// /// 上传一个新用户id分数 /// public void UploadNewIdScore() { int newUserId = RankService.GenerateLocalUserId(); int seed = 0; var random = seed == 0 ? new System.Random() : new System.Random(seed); int score = random.Next(0, 1000); // 0~999 分之间 RankService.UploadScore(gameId, newUserId, "Player_" + newUserId, "", score); Debug.Log($"UploadNewIdScore rank_game_{gameId} 上传 新Id:{newUserId}分数!"); GetLocalRankList(); } #region 测试数据操作 /// /// 测试数据调用 /// public void TestData() { InsertTestData(); } /// /// 按钮调用,重新填充排行榜数据 /// // public void AnimatorRunButton() // { // PopulateRankList(true); // 重新填充排行榜数据 // } /// /// 插入测试数据 /// /// private void InsertTestData(int seed = 0) { var random = seed == 0 ? new System.Random() : new System.Random(seed); for (int i = 1; i <= 20; i++) { int userId = 1000 + i; string nickname = $"玩家{i:D2}"; string avatarUrl = ""; // 可以填测试图片链接或留空 int score = random.Next(0, 10000); // 0~9999 分之间 RankService.UploadScore(gameId, userId, nickname, avatarUrl, score); } Debug.Log($"已为 gameId={gameId} 插入 20 条测试数据"); } #endregion /// /// 获取本地排行榜 /// void GetLocalRankList() { rankDataList.Clear(); RankItemData selfItem = null; const int MaxRankDisplayCount = 9; // 展示排行榜上限,最后一位预留给自己 int maxRank = 0;//记录最大的max int index = 0;//当前下标 var (ranks, selfRank, total) = RankService.GetRankList(gameId: gameId, userId: userId); foreach (var r in ranks) { Debug.Log($"[{r.Rank}] {r.Nickname} - {r.Score} {(r.IsSelf ? "(你)" : "")}"); var data = new RankItemData { Rank = r.Rank, UserName = r.Nickname, Score = r.Score, AvatarUrl = r.AvatarUrl, IsSelf = r.IsSelf, RankIndex = index++ }; // Debug.Log($"成功解析data {data} 排行榜数据"); if (data.IsSelf) selfItem = data; else rankDataList.Add(data); maxRank = Mathf.Max(maxRank, r.Rank);//记录最大值 } //Debug.Log($"成功解析 {rankDataList.Count} 条排行榜数据"); // 如果总数量不足 MaxRankDisplayCount,补充假数据 int currentCount = rankDataList.Count; int otherIndex = 0; for (int i = currentCount; i < MaxRankDisplayCount; i++) { ++otherIndex; var fakeData = new RankItemData { Rank = maxRank + otherIndex, UserName = $"游客玩家 {i + 1}", Score = 0, AvatarUrl = "", // 可替换为默认头像路径 IsSelf = false, RankIndex = index++ }; rankDataList.Add(fakeData); } // 最后添加自己(先放在最后一位) if (selfItem != null) { rankDataList.Add(selfItem); } // Debug.Log($"最终排行榜数据条数: {rankDataList.Count}"); PopulateRankList(true); } /// /// 获取远程排行榜数据 /// 暂时不使用 /// /// private IEnumerator FetchRankDataFromServer() { string url = "http://192.168.0.108:11432/SmartBowBusinessServer/SmartBowSDK/UploadScoreAndGetSeasonCenterRankList" + "?token=3421-1746758375311-5786b88c34343d142bea1dd31a1cb315" + "&rankArea=2&rankGameType=1001&score=9937" + "&countryCode=中国&stateCode=广东省&cityCode=清远市"; UnityWebRequest request = UnityWebRequest.Post(url, ""); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError("Request Failed: " + request.error); yield break; } string json = request.downloadHandler.text; ParseRankJson(json); } /// /// 解析远程排行榜数据 /// /// private void ParseRankJson(string json) { rankDataList.Clear(); JObject root = JObject.Parse(json); JArray rankArray = (JArray)root["data"][0]; RankItemData selfItem = null; int index = 0; foreach (JObject item in rankArray) { var data = new RankItemData { Rank = item["rankNum"] != null ? (int)item["rankNum"] : 0, UserName = item["nickname"]?.ToString() ?? "Unknown", Score = item["score"] != null ? (int)item["score"] : 0, AvatarUrl = item["avatarUrl"]?.ToString() ?? "", IsSelf = item["isSelf"]?.ToObject() ?? false, RankIndex = index++ }; Debug.Log($"成功解析data {data} 排行榜数据"); if (data.IsSelf) selfItem = data; else rankDataList.Add(data); } // 最后添加自己(先放在最后一位) if (selfItem != null) { rankDataList.Add(selfItem); } Debug.Log($"成功解析 {rankDataList.Count} 条排行榜数据"); PopulateRankList(); } /// /// 开始跑循环分数时候调用 /// public void HideAllRankIcons() { for (int i = 0; i < content.childCount; i++) { var item = content.GetChild(i); var itemUI = item.GetComponent(); if (itemUI != null) { //itemUI.HideIconAndText(); itemUI.StartRunUI(); } } } /// /// 结束循环分数时候调用 /// public void RefreshRankIcons() { for (int i = 0; i < content.childCount; i++) { var item = content.GetChild(i); var itemUI = item.GetComponent(); if (itemUI != null) { itemUI.StopRunUI(); } } } /// /// 填充排行榜列表,生成排行榜预制item /// /// private void PopulateRankList(bool isStartup = false) { foreach (Transform child in content) Destroy(child.gameObject); for (int i = 0; i < rankDataList.Count; i++) { var data = rankDataList[i]; GameObject itemObj = Instantiate(itemPrefab, content); itemObj.name = $"RankItem_{data.Rank}"; RankItemUI itemUI = itemObj.GetComponent(); if (itemUI != null) { itemUI.SetData(data); if (!string.IsNullOrEmpty(data.AvatarUrl)) StartCoroutine(LoadAvatarImage(data.AvatarUrl, itemUI.avatarImage)); } else { Debug.LogWarning("预制体上缺少 RankItemUI 脚本"); } } if (isStartup) StartCoroutine(DelayedStartAnimation()); } /// /// 加载头像图片 /// /// /// /// private IEnumerator LoadAvatarImage(string url, Image targetImage) { UnityWebRequest request = UnityWebRequestTexture.GetTexture(url); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogWarning("头像加载失败: " + request.error); yield break; } Texture2D texture = DownloadHandlerTexture.GetContent(request); Sprite avatarSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); targetImage.sprite = avatarSprite; } /// /// 延迟开始动画 /// /// IEnumerator DelayedStartAnimation() { yield return null; // TestRankUpFromTo(10, 1); //查找“自己”的索引和目标真实排名索引 int startIndex = rankDataList.Count; RankItemData selfData = rankDataList.Find(d => d.IsSelf); int targetIndex = selfData.RankIndex + 1; // 目标名次是自己在列表中的索引 + 1 // for (int i = 0; i < rankDataList.Count; i++) // { // var data = rankDataList[i]; // Debug.Log($"[{data.Rank}] {data.UserName} - {data.Score} {(data.IsSelf ? "(你)" : "")} ,RankIndex: {data.RankIndex}"); // } // Debug.Log($"startIndex:{startIndex} targetIndex:{targetIndex}"); if (startIndex != targetIndex) { RankUpFromTo(startIndex, targetIndex); } } /// /// 测试冲榜动画:从 startIndex 冲到 targetRankIndex /// void RankUpFromTo(int startIndex, int targetRankIndex) { if (startIndex <= 0 || startIndex > content.childCount) { Debug.LogError("无效的起始排名!"); return; } if (targetRankIndex <= 0 || targetRankIndex > content.childCount) { Debug.LogError("无效的目标排名!"); return; } // 获取起始 item Transform startItem = content.GetChild(startIndex - 1); // 设置 animator 的目标元素和目标名次 rankUpAnimator.targetItem = startItem.GetComponent(); rankUpAnimator.targetRankIndex = targetRankIndex; // 调用冲榜动画 rankUpAnimator.StartRankUpAnimation(startIndex, targetRankIndex); } } }