using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Collections; using UnityEngine.Networking; using Newtonsoft.Json.Linq; using System; namespace LocalRank { [RequireComponent(typeof(RankUpAnimator))] public class RankManager : MonoBehaviour { public Transform Panel; //是否显示 public Transform content; // Content节点 public GameObject itemPrefab; // 排行榜Item预制体 public InputField inputField; private RankUpAnimator rankUpAnimator; // RankUpAnimator脚本引用 private List rankDataList = new List(); /// /// 当前的排名分数 /// public static int CurrentScore = 0; /// /// 维护一个全局的userId /// public static int userId { get; private set; } /// /// 是否创建userId /// private static bool userIdCreated = false; public static bool HasUserId => userIdCreated; /// /// 是否在滚动 /// private bool isRuning = false; //退出 public Action OnBackClicked; // 你可以在这里定义游戏 ID 或者动态获取 private int gameId = 1; /// /// 创建一个排行榜 /// /// public static void CreateRankView(int gameType,Action callback) { Debug.Log("当前上传的本地排行榜ID:"+ gameType); //b端时候处理一个结束排行榜 GameObject rankObj = ViewManager2.getGameObjectAndShowView(ViewManager2.Path_GameRankView); RankManager gameRankView = rankObj.GetComponent(); gameRankView.OnBackClicked += ()=> { ViewManager2.HideView(ViewManager2.Path_GameRankView); callback?.Invoke(); }; gameRankView.CreateRankGameInfo(gameType); gameRankView.UploadCurrentScoreToNewId(); } private void Awake() { rankUpAnimator = GetComponent(); if (rankUpAnimator == null) { Debug.LogError("RankUpAnimator 组件未找到!"); } if (inputField != null) { inputField.onEndEdit.AddListener(InputScore); } } private void Start() { rankUpAnimator.onAnimationStart = () => { isRuning = true; HideAllRankIcons(); // 滚动前隐藏图标和名次数字 }; rankUpAnimator.onAnimationComplete = () => { isRuning = false; RefreshRankIcons(); // 滚动后恢复图标或数字 }; //CreateRankGameInfo(); //CreateUserId(); } /// /// 设置分数。用于后续上传排行榜显示 /// /// public static void SetCurrentScore(int score = 0) { if (score > 0) { CurrentScore = score; } } /// /// 创建本地排行榜,进入场景时候直接创建。比如游戏场景 /// 不同的游戏ID对应不同的排行榜 /// public void CreateRankGameInfo(int CurrentGameId = 1) { gameId = CurrentGameId; // 判断是否已创建表 if (RankService.IsTableExists(gameId)) { Debug.Log($"rank_game_{gameId} 表已存在!"); } else { Debug.Log($"rank_game_{gameId} 表不存在,正在创建..."); RankService.CreateTableIfNotExists(gameId); } } /// /// 如果需要维护一个常用id的话 /// 调用这里创建userId,每个userId都是单独记录排行榜数据。 /// public void CreateUserId() { //获取一个时间戳值 userId = RankService.GenerateLocalUserId(); //记录一个标识 userIdCreated = true; } /// /// 直接上传分数到当前用户信息 /// public void UploadCurrentScoreToUserId() { if (!HasUserId) { Debug.LogError("无效的本地用户id!"); return; } if (CurrentScore != 0) { if (isRuning) { Debug.LogError("操作频繁!等排行榜停止在操作!"); return; } RankService.UploadScore(gameId, userId, "Player_" + userId, "", CurrentScore); Debug.Log($"UploadScoreToUserId rank_game_{gameId} 上传 Id:{userId}分数:{CurrentScore}!"); GetLocalRankList(); CurrentScore = 0; } } /// /// 上传当前操作分数到新用户 /// public void UploadCurrentScoreToNewId() { if (CurrentScore != 0) { if (isRuning) { Debug.LogError("操作频繁!等排行榜停止在操作!"); return; } Panel.gameObject.SetActive(true); UploadNewIdScore(CurrentScore); CurrentScore = 0; } else { //分数是0直接进行下一步 OnBackClicked?.Invoke(); } } /// /// 直接上传一个新用户id分数 /// private void UploadNewIdScore(int score = 0) { int newUserId = RankService.GenerateLocalUserId(); RankService.UploadScore(gameId, newUserId, "Player_" + newUserId, "", score); Debug.Log($"UploadNewIdScore rank_game_{gameId} 上传 新Id:{newUserId}分数:{score}!"); //更新当前用户信息 userId = newUserId; userIdCreated = true; GetLocalRankList(); } #region 测试数据操作 /// /// 通过Input End 上传分数 /// /// void InputScore(string score) { if (!HasUserId) { Debug.LogError("无效的本地用户id!"); return; } int parsedScore; if (!int.TryParse(score, out parsedScore)) { Debug.LogError("输入的分数无效!"); return; } if (isRuning) { Debug.LogError("操作频繁!等排行榜停止在操作!"); return; } RankService.UploadScore(gameId, userId, "Player_" + userId, "", parsedScore); Debug.Log($"InputScore rank_game_{gameId} 上传 Id:{userId}分数:{parsedScore}"); GetLocalRankList(); } /// /// 上传测试分数 /// /// public void UploadTestRandomScoreToUserId() { if (!HasUserId) { Debug.LogError("无效的本地用户id!"); return; } if (isRuning) { Debug.LogError("操作频繁!等排行榜停止在操作!"); return; } 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($"UploadTestRandomScoreToUserId rank_game_{gameId} 上传 Id:{userId}分数:{_score}!"); GetLocalRankList(); } /// /// 上传随机分数到新用户 /// public void UploadTestRandomScoreToNewId() { if (isRuning) { Debug.LogError("操作频繁!等排行榜停止在操作!"); return; } int seed = 0; var random = seed == 0 ? new System.Random() : new System.Random(seed); int _score = random.Next(1, 1000); // 随机的分数是 1~999 分之间 UploadNewIdScore(_score); } /// /// 测试数据调用 /// 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() { if (!HasUserId) { Debug.LogError("先创建用户id再获取排行榜!"); return; } 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); } public void OnClick_Back() { if (isRuning) return; //AudioMgr.ins.PlayBtn(); OnBackClicked?.Invoke(); } } }