using GameCore; using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using UnityEngine; public class ConvertTools { public static string ConvertTime2(int d, int h, int m, int s) { string str = ""; int showCount = 0; int maxShowCount = 2; if (d > 0) { showCount++; str = $"{d}d "; } if (h > 0) { showCount++; str += $"{h}h "; } if (showCount >= maxShowCount) { return str; } else if (m > 0) { showCount++; str += $"{m}m "; } if (showCount >= maxShowCount) { return str; } else if (s > 0) { str += $"{s}s "; } return str; } public static string ConvertTime2(TimeSpan timer) { return ConvertTime2(timer.Days, timer.Hours, timer.Minutes, timer.Seconds); } /// /// Only One Number, negative time will be considered as 0. /// /// /// public static string ConvertTime3(TimeSpan timer) { if (timer.Days > 0) { return $"{timer.Days}d "; } if (timer.Hours > 0) { return $"{timer.Hours}h "; } if (timer.Minutes > 0) { return $"{timer.Minutes}m "; } if (timer.Seconds > 0) { return $"{timer.Seconds}s "; } return "0s "; } /// /// hh:mm:ss /// /// /// public static string ConvertTime(TimeSpan timer) { return timer.ToString(@"hh\:mm\:ss"); } public static string ConvertTime4(TimeSpan timer) { return timer.Hours > 0 ? ConvertTime(timer) : timer.ToString(@"mm\:ss"); } public static DateTime GetDateTimeYMD(DateTime date) { return new DateTime(date.Year, date.Month, date.Day); } public static DateTime GetDateTimeSunDay(DateTime date) { var dayOfWeek = (int)date.DayOfWeek; int offset = 7 - (dayOfWeek == 0 ? 7 : dayOfWeek); return GetDateTimeYMD(date.AddDays(Mathf.Abs(offset))); } /// /// ("#,##0.#") /// /// /// public static string GetNumberString(ulong num, bool keep = false) { string format = keep ? "#,##0.0" : "#,##0.#"; string str; if (num < 1000) { str = num.ToString("#,##0"); } else if (num < 1000000) { float fnum = Mathf.Floor(num / 100f) / 10; str = fnum.ToString(format) + "K"; } else if (num < 1000000000) { float fnum = Mathf.Floor(num / 100000f) / 10; str = fnum.ToString(format) + "M"; } else { float fnum = Mathf.Floor(num / 100000000f) / 10; str = fnum.ToString(format) + "G"; } return str; } public static int KeepThreeSignificantDigits(int value) { if (value <= 0) return 0; int digits = (int)Math.Floor(Math.Log10(value)) + 1; if (digits <= 3) return value; int digitsToRemove = digits - 3; int factor = (int)Math.Pow(10, digitsToRemove); int rounded = value / factor * factor; return rounded; } /// /// ("#,##0.#") /// /// /// public static string GetNumberString(int num, bool keep = false) { string format = keep ? "#,##0.0" : "#,##0.#"; string str; if (num < 1000) { str = num.ToString("#,##0"); } else if (num < 1000000) { float fnum = Mathf.Floor(num / 100f) / 10; str = fnum.ToString(format) + "K"; } else { float fnum = Mathf.Floor(num / 100000f) / 10; str = fnum.ToString(format) + "M"; } return str; } /// /// 折扣显示 /// /// /// public static string GetNumberString3(float num) { string str = ""; if (num <= 1) { var discount = (1 - num) * 100; var decimalPart = discount - (int)discount; // if ( decimalPart < 0.001f ) str = discount.ToString("F0"); // else // str = discount.ToString("F1"); } else Debug.LogError("[ConverTools::GetNumberString3] Discount Exceeds 1"); return str + "%"; } public static string GetDiscountStringActual(float discount) { discount *= 100; var res = discount.ToString("F0"); return res + "%"; } public static string GetNumberStringRetain(double num, bool keep) { string str = ""; if (num < 0.1) { str = num.ToString("##0.00"); } else if (keep) { str = num.ToString("##0.0"); } else { str = num.ToString("##0.#"); } return str; } /// /// ("#,##0") /// /// /// public static string GetNumberString2(ulong num) { //输出类似713,999,999 return num.ToString("#,##0"); } /// /// ("#,##0") /// /// /// public static string GetNumberString2(long num) { //输出类似713,999,999 return num.ToString("#,##0"); } /// /// ("#,##0") /// /// /// public static string GetNumberString2(int num) { //输出类似713,999,999 return num.ToString("#,##0"); } /// /// 场景到UI 的坐标转换 /// /// 场景中的全局坐标 /// 是否转换成相对于UIRoot的局部坐标 /// public static Vector3 WorldToScreenPoint(Vector3 pos, bool local = true) { Vector3 targetPos = Camera.main.WorldToScreenPoint(pos); Vector2 sizeDelta = UIManager.Instance.RectTrans.sizeDelta; //先获取主画布下的分辨率宽高: float resolutionRatioWidth = sizeDelta.x; float resolutionRatioHeight = sizeDelta.y; //计算主画布分辨率下的宽高和屏幕的宽高的比列: float widthRatio = resolutionRatioWidth / Screen.width; float heightRatio = resolutionRatioHeight / Screen.height; //先分别乘以宽高比值 targetPos.x *= widthRatio; targetPos.y *= heightRatio; //计算在中心点的屏幕坐标 targetPos.x -= resolutionRatioWidth * 0.5f; targetPos.y -= resolutionRatioHeight * 0.5f; if (local) { return targetPos; } return UIManager.Instance.RectTrans.transform.TransformPoint(targetPos); } /// /// 将3D场景的坐标转化为某个UI组件下的局部坐标。 /// /// 3D场景下的坐标 /// 目标UI组件,默认为UIRoot,但UIRoot可能会有刘海屏适配bug。 /// 相对于uiRectTransform的局部UI坐标 public static Vector2 WorldToUiLocalPosition(Vector3 worldPosition, RectTransform uiRectTransform = null) { // uiRectTransform ??= UIManager.Instance.RectTrans; var screenPoint = RectTransformUtility.WorldToScreenPoint(Camera.main, worldPosition); return screenPoint; // Debug.Log($"ScreenPoint: {screenPoint}"); // RectTransformUtility.ScreenPointToLocalPointInRectangle(uiRectTransform, screenPoint, Camera.main, out var localHitPosition); // Debug.Log($"localHitPosition: {localHitPosition}"); // return localHitPosition; } public static string Encrypt(string text, string key) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.Key = Encoding.ASCII.GetBytes(key); des.IV = Encoding.ASCII.GetBytes(key); ICryptoTransform encryptor = des.CreateEncryptor(des.Key, des.IV); byte[] inputBytes = Encoding.UTF8.GetBytes(text); byte[] outputBytes = encryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length); return Convert.ToBase64String(outputBytes); } const string RTMKey = "tbambooz"; public static string Decrypt(string text) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.Key = Encoding.ASCII.GetBytes(RTMKey); des.IV = Encoding.ASCII.GetBytes(RTMKey); ICryptoTransform decryptor = des.CreateDecryptor(des.Key, des.IV); byte[] inputBytes = Convert.FromBase64String(text); byte[] outputBytes = decryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length); return Encoding.UTF8.GetString(outputBytes); } /// /// 计算相机偏转限制 /// /// 为正数0-180 /// public static float CalculateActualRotationAngle(float configuredRotationAngle) { float fovRad = 30 * Mathf.Deg2Rad; float rotationAngleRad = configuredRotationAngle * Mathf.Deg2Rad; float aspectRatio = Screen.width / (float)Screen.height; aspectRatio = Mathf.Clamp(aspectRatio, 0.45f, 1); aspectRatio = Mathf.Atan(Mathf.Tan(fovRad) * aspectRatio); float actualRotationAngleRad = Mathf.Max(0, rotationAngleRad - aspectRatio); float actualRotationAngle = actualRotationAngleRad * Mathf.Rad2Deg; return actualRotationAngle; } public static string ConvertActiveTime(TimeSpan t) { if (t.Days > 0) { return ""; } if (t.Hours > 0) { return $"{t.Hours}h"; } if (t.Minutes > 0) { return $"{t.Minutes}m"; } if (t.Seconds > 0) { return $"{t.Seconds}s"; } return "0s"; } static public void SetFSBlur(bool isActive, float depth = 6) { var feature = zzwater.URPHelper.FindAndCacheRendererFeature("FSBlur"); if (feature == null) Debug.LogError($"Feature FSWave not found"); else { feature.SetActive(isActive); if (isActive) { FullScreenPassRendererFeature fullScreenPassRendererFeature = feature as FullScreenPassRendererFeature; Material material = fullScreenPassRendererFeature.passMaterial; if (material != null) { material.SetFloat("_DepthThreshold", depth); } } } } /// /// 对List进行原地洗牌(Fisher-Yates算法) /// /// 需要打乱的列表 public static List Shuffle(List list, System.Random _random) { List newlist = new List(list); // 空列表/单元素列表无需打乱 if (newlist == null || newlist.Count <= 1) return newlist; // Fisher-Yates 核心逻辑:从后往前遍历,逐个交换随机位置 for (int i = newlist.Count - 1; i > 0; i--) { // 生成 0 到 i(包含i)之间的随机索引 int randomIndex = _random.Next(0, i + 1); // 交换当前元素和随机位置的元素 (newlist[i], newlist[randomIndex]) = (newlist[randomIndex], newlist[i]); } return newlist; } }