先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
424 lines
12 KiB
C#
424 lines
12 KiB
C#
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Only One Number, negative time will be considered as 0.
|
||
/// </summary>
|
||
/// <param name="timer"></param>
|
||
/// <returns></returns>
|
||
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 ";
|
||
}
|
||
/// <summary>
|
||
/// hh:mm:ss
|
||
/// </summary>
|
||
/// <param name="timer"></param>
|
||
/// <returns></returns>
|
||
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)));
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// ("#,##0.#")
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// ("#,##0.#")
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 折扣显示
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// ("#,##0")
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
public static string GetNumberString2(ulong num)
|
||
{
|
||
//输出类似713,999,999
|
||
|
||
return num.ToString("#,##0");
|
||
}
|
||
|
||
/// <summary>
|
||
/// ("#,##0")
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
public static string GetNumberString2(long num)
|
||
{
|
||
//输出类似713,999,999
|
||
|
||
return num.ToString("#,##0");
|
||
}
|
||
|
||
/// <summary>
|
||
/// ("#,##0")
|
||
/// </summary>
|
||
/// <param name="num"></param>
|
||
/// <returns></returns>
|
||
public static string GetNumberString2(int num)
|
||
{
|
||
//输出类似713,999,999
|
||
|
||
return num.ToString("#,##0");
|
||
}
|
||
/// <summary>
|
||
/// 场景到UI 的坐标转换
|
||
/// </summary>
|
||
/// <param name="pos">场景中的全局坐标</param>
|
||
/// <param name="local">是否转换成相对于UIRoot的局部坐标</param>
|
||
/// <returns></returns>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将3D场景的坐标转化为某个UI组件下的局部坐标。
|
||
/// </summary>
|
||
/// <param name="worldPosition">3D场景下的坐标</param>
|
||
/// <param name="uiRectTransform">目标UI组件,默认为UIRoot,但UIRoot可能会有刘海屏适配bug。</param>
|
||
/// <returns>相对于uiRectTransform的局部UI坐标</returns>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算相机偏转限制
|
||
/// </summary>
|
||
/// <param name="configuredRotationAngle">为正数0-180</param>
|
||
/// <returns></returns>
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对List<int>进行原地洗牌(Fisher-Yates算法)
|
||
/// </summary>
|
||
/// <param name="list">需要打乱的列表</param>
|
||
public static List<int> Shuffle(List<int> list, System.Random _random)
|
||
{
|
||
List<int> newlist = new List<int>(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;
|
||
}
|
||
}
|