NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Utils/CommonUtils.cs

1526 lines
49 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using cfg.VihecleCultivateCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay.Character.Utils;
using Gameplay.Level;
using Newtonsoft.Json;
using NLDPB;
using PhxhSDK;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using cfg;
using cfg.CharacterCfg;
using Gameplay.Unit;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;
using Constants = Framework.Constants;
using Object = UnityEngine.Object;
using cfg.ActorCfg;
using UnityEngine.SceneManagement;
using Random = UnityEngine.Random;
using cfg.ErrorCfg;
using cfg.FightCfg;
using cfg.LevelCfg;
using Gameplay.SubSystems;
using PhxhSDK.Res;
using System.Collections;
using Sirenix.Utilities;
namespace Gameplay
{
public partial class CommonUtils
{
public static RenderTexture screenTexture;
private static readonly int MainTex = Shader.PropertyToID("_MainTex");
private static readonly int BlurSize = Shader.PropertyToID("_BlurSize");
private static readonly int ForceGray = Shader.PropertyToID("_ForceGray");
private const string ICON_WEATHER_PREFIX = "Icon_Weather_";
private const string ICON_ENVIRONMENT_PREFIX = "Icon_Environment_";
private const string ICON_DAYNIGHT_PREFIX = "Icon_Daynight_";
private const string SCREEN_SNAPSHOT = "ScreenSnapshot";
public static void DestoryGameObjectImmediate(ref GameObject obj)
{
if (null != obj)
{
GameObject.DestroyImmediate(obj);
obj = null;
}
}
public static string GetInternaitionalStr(int strId, string str)
{
return str;
}
public static GameObject GetGameObject(GameObject gameObject, string path)
{
Transform tra = gameObject.transform.Find(path);
return null != tra ? tra.gameObject : null;
}
public static T GetComponent<T>(GameObject gameObject, string path = null) where T : Component
{
T result = null;
if (null == gameObject)
{
DebugUtil.LogWarning("ParentObjectisNUll: {0}", path);
}
if (null != path)
result = gameObject.transform.Find(path).gameObject.GetComponent<T>();
else
result = gameObject.GetComponent<T>();
if (result == null)
{
DebugUtil.Log(path);
}
return result;
}
//获取对象子节点中最上层的那个组件
public static T GetChildComponent<T>(GameObject go) where T : Component
{
T result = null;
if (!go)
{
DebugUtil.LogWarning("ParentObjectisNUll: {0}", go.name);
}
var trans = go.transform;
for (int i = 0; i < trans.childCount; i++)
{
var child = trans.GetChild(i);
var cmp = child.GetComponent<T>();
if (cmp)
{
result = cmp;
break;
}
//递归搜索子节点的子节点,返回最上层那个
result = GetChildComponent<T>(child.gameObject);
if (result)
{
break;
}
}
return result;
}
public static void DestoryAllChildGameObject(GameObject parent)
{
if (parent != null)
{
int count = parent.transform.childCount;
List<Transform> childs = new List<Transform>();
for (int i = 0; i < count; ++i)
{
childs.Add(parent.transform.GetChild(i));
}
for (int i = 0; i < count; ++i)
{
GameObject.DestroyImmediate(childs[i].gameObject);
}
}
}
//???????????
public static string GetWholeHeadPath(string name)
{
return TableManager.Instance.Tables.GlobalConfig.HeadPicFrontPath + name + ".png";
}
public static string GetDefaultHeadPathByUid(uint uid)
{
var cfg = TableManager.Instance.Tables.CharacterAttri.GetOrDefault((int)uid);
if (cfg == null)
{
DebugUtil.LogError("--- 无法获取UID对应的配置 ---");
return "";
}
var skinIdx = cfg.DefaultSkinIndex;
var dataSkin = TableManager.Instance.Tables.SkinCfg.Get(skinIdx, cfg.RoleID);
return GetWholeHeadPath(dataSkin.PIcHeadPath);
}
public static string GetDefaultVehicleHeadPath(uint uid)
{
var cfg = TableManager.Instance.Tables.VehicleConfig.GetOrDefault((int)uid);
if (cfg == null)
{
DebugUtil.LogError("--- 无法获取UID对应的配置 ---");
return "";
}
return cfg.UIHeadPath;
}
public static Ejob GetProfessionByUid(uint uid)
{
var cfg = TableManager.Instance.Tables.CharacterAttri.GetOrDefault((int)uid);
if (cfg == null)
{
DebugUtil.LogError("--- 无法获取UID对应的配置 ---");
return default;
}
return cfg.Job;
}
//????????
public static string GetWholeLiHuiPath(string name)
{
return Constants.UI_POSTER_DEFAULT_PATH + name + ".png";
}
public static string GetVehicleHeadPath(string name)
{
return name + ".png";
}
public enum ECharacterPicPathType
{
Cultivate,//养成主界面用,大半身图
Favorable,//好感度界面用,全身立绘
LevelUp,//技能升级界面用,全身不同尺寸立绘
SelectCharacter,//选择角色界面用,半身
Poster,//立绘查看界面用,全身
}
public static string GetCharacterPicPath(int id, ECharacterPicPathType eCharacterPicPathType, int skinID = 1)
{
cfg.CharacterCfg.SkinCfg postCfg = TableManager.Instance.Tables.SkinCfg;
if (postCfg.Get(skinID, id) == null)
{
DebugUtil.LogError("该id的posterCfg尚未配置", id);
return @"Assets/Art/UI/Texture/UI_Pic_Main/UI_Poster/Cutivate/Poster_Cul_001.png";
}
switch (eCharacterPicPathType)
{
case ECharacterPicPathType.Cultivate:
return @"Assets/Art/UI/Texture/UI_Pic_Main/UI_Poster/Cutivate/" + postCfg.Get(1, id).Cultivate + ".png";
case ECharacterPicPathType.Favorable:
return @"Assets/Art/UI/Texture/UI_Pic_Main/UI_Poster/Favorate/" + postCfg.Get(1, id).Favorable + ".png";
case ECharacterPicPathType.LevelUp:
return @"Assets/Art/UI/Texture/UI_Pic_Main/UI_Poster/LevelUp/" + postCfg.Get(1, id).LevelUp + ".png";
case ECharacterPicPathType.SelectCharacter:
return @"Assets/Art/UI/Texture/UI_Pic_Main/UI_Poster/Select/" + postCfg.Get(1, id).SelectCharacter + ".png";
case ECharacterPicPathType.Poster:
return @"Assets/Art/UI/Texture/Poster/Poster_Default/" + postCfg.Get(1, id).Poster + ".png";
}
return null;
}
//获取同一角色的皮肤配置列表
public static List<DataCharacterSkin> GetCharacterSkinCfgList(int uid)
{
var retList = new List<DataCharacterSkin>();
var cfg = TableManager.Instance.Tables.SkinCfg;
for (int i = 0; i < cfg.DataList.Count; i++)
{
var dataCfg = cfg.DataList[i];
if (dataCfg.RoleID == uid)
{
int curIdx = i;
while (curIdx < cfg.DataList.Count)
{
var curDataCfg = cfg.DataList[curIdx];
if (curDataCfg.RoleID != uid)
{
break;
}
retList.Add(cfg.DataList[curIdx]);
++curIdx;
}
break;
}
}
return retList;
}
//}
//public static string GetVehiclePath(int id)
//{
//}
//???????
/// <summary>
/// 获取本地化文本
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetLocalizeText(string key)
{
return StringManager.Instance.GetLocalizeTextByKey(key);
}
public static string GetLocalizeText(string key, params object[] param)
{
string str = StringManager.Instance.GetLocalizeTextByKeyAndParams(key, param);
return str;
}
public static void SetScaleWithCameraOrgSize(GameObject go)
{
var camera = CameraManager.Instance.MainCamera;
var cameraCtrller = camera.gameObject.GetComponent<CameraController>();
int minSize = 6;
if (cameraCtrller)
{
minSize = (int)cameraCtrller.CameraMinSize;
}
float curSize = camera.orthographicSize;
float mul = minSize / curSize;
go.transform.localScale = new Vector3(mul, mul, mul);
}
//图片灰显开启
public static async UniTask OpenImageGray(Image img)
{
var mat = await AssetManager.Instance.LoadAssetAsync<Material>("Assets/Art/UI/Material/mat_GrayUI.mat");
if (mat)
{
var material = UnityEngine.Object.Instantiate(mat);
img.material = material;
}
}
public static async void SetImageGray(Image img, bool isGray)
{
int param = isGray ? 1 : 0;
bool dontHaveGrayMat = true;
if (img.material)
{
if (img.material.shader.name == "NLD_URP/NLD_UI_Gray")
{
dontHaveGrayMat = false;
}
}
if (dontHaveGrayMat)
{
await OpenImageGray(img);
}
img.material.SetInt(ForceGray, param);
}
public static void ConsoleOpResultError(uint o)
{
OpResult opResult = (OpResult)o;
bool isShowForPlayer = false;
DataErrorCfg errorCfg= TableManager.Instance.Tables.ErrorLogCfg.Get((int)o);
if(errorCfg!=null)
{
isShowForPlayer = errorCfg.IsShowToPlayer;
//DebugUtil.LogError("请在errorLog中补上id为{0}的表",o);
}
if (isShowForPlayer)
{
if (errorCfg != null)
{
ShowMessageTips(GetLocalizeText("OpResult"+o) + "," + string.Format(GetLocalizeText("errorIdDesc"), o));
}
else
{
//DebugUtil.LogError("提供给用户显示的errorLog没有", o);
}
}
}
public static string GetRomanCode(int i)//获取1到6的罗马数字
{
switch (i)
{
case 0:
return "0";
case 1:
return "I";
case 2:
return "II";
case 3:
return "III";
case 4:
return "IV";
case 5:
return "V";
case 6:
return "VI";
}
DebugUtil.LogError("你要的罗马数字还没有");
return "";
}
public static string GetShootMode(EShootMode shootMode)
{
switch (shootMode)
{
case EShootMode.Rapidfire:
return GetLocalizeText("Rapidfire");
case EShootMode.Burstfire:
return GetLocalizeText("Burstfire");
}
DebugUtil.LogError("射击模式{0}没有配本地化,请在stringConfig中配齐", shootMode);
return shootMode.ToString();
}
private static async UniTask OpenImageBlur(Image image)
{
var mat = await AssetManager.Instance.LoadAssetAsync<Material>("Assets/Art/UI/Material/NLD_URP_NLD_UI_Blur.mat");
if (mat)
{
var material = UnityEngine.Object.Instantiate(mat);
image.material = material;
}
}
public static void CaptureScreenshot()
{
screenTexture = screenTexture == null
? RenderTexturePool.Instance.Create(SCREEN_SNAPSHOT, Screen.width, Screen.height, 0)
: screenTexture;
var uiCamera = CameraManager.Instance.UICamera;
var additionalCameraData = uiCamera.GetComponent<UniversalAdditionalCameraData>();
CameraRenderType tempRenderType = additionalCameraData.renderType;
var oldRenderTarget = uiCamera.targetTexture;
additionalCameraData.renderType = CameraRenderType.Base;
uiCamera.targetTexture = screenTexture;
uiCamera.Render();
uiCamera.targetTexture = oldRenderTarget;
additionalCameraData.renderType = tempRenderType;
// Apply the captured screen texture to the blur material
}
public static async void SetImageBlur(Image img)
{
bool dontHaveMat = true;
if (img.material)
{
if (img.material.shader.name == "NLD_URP/NLD_UI_Blur")
{
dontHaveMat = false;
}
}
if (dontHaveMat)
{
await OpenImageBlur(img);
}
img.material.SetTexture(MainTex, screenTexture);
img.material.SetInt(BlurSize, 10);
}
public static async void RefreshCharacter2DPic(Image img, int roleId, ECharacterPicPathType eCharacterPicPathType)
{
img.gameObject.SetActive(false);
string imgPath = GetCharacterPicPath(roleId, eCharacterPicPathType);
if (imgPath != null)
{
//await AssetManager.Instance.LoadAssetAsync<Sprite>(imgPath, spr =>
// {
// img.sprite = spr;
// img.gameObject.SetActive(true);
// });
img.sprite = await AssetManager.Instance.LoadAssetAsync<Sprite>(imgPath);
img.gameObject.SetActive(true);
}
}
public static int GetGameUnitUltraSkillID(GameUnit unit)
{
uint uid = unit.GetID();
return GetGameUnitUltraSkillID(uid);
}
public static int GetGameUnitUltraSkillID(uint uid)
{
CharacterDataInfo characterDataInfo;
if (CharacterDataInfoManager.Instance.DataDic.TryGetValue(uid, out characterDataInfo))
{
return CharacterDataHelper.GetCharacterSkillId(characterDataInfo);
}
DebugUtil.LogError("请检查传入的角色对象uid");
return 0;
}
public static string WWWLoadText(string fileName)
{
UnityWebRequest www = UnityWebRequest.Get(fileName);//WWW会自动开始读取文件
while (!www.isDone) { }//WWW是异步读取所以要用循环来等待
return www.downloadHandler.text;
}
public static string FormatNumber(long num)
{
return string.Format("{0:N0}", num);
}
public static string FormatNumber(float num)
{
return string.Format("{0:N0}", num);
}
public static string FormatMoney(float num)
{
return num.ToString("C2");
}
public static string FormatSize(float fBytes)
{
if (fBytes <= 0)
{
return "0K";
}
else if (fBytes < 102.4f)
{
return "0.1K";
}
else if (fBytes < 1024 * 1024)
{
return string.Format("{0:F1}K", (fBytes / 1024));
}
else
{
return string.Format("{0:F1}M", (fBytes / (1024 * 1024)));
}
}
public static string Validate(string text)
{
//https://msdn.microsoft.com/en-us/library/20bw873z(v=vs.110).aspx
text = RemoveEmoji(text, @"\p{C}");
return text;
}
static string ValidateEx(string text)
{
//https://en.wikipedia.org/wiki/Emoji#Emoji_in_the_Unicode_standard
// 635 of the 766 codepoints in the Miscellaneous Symbols and Pictographs block are considered emoji.
string pattern = @"[^\u1F300-\u1F5FF]";
text = RemoveEmoji(text, pattern);
// All of the 15 codepoints in the Supplemental Symbols and Pictographs block are considered emoji.
pattern = @"[^\u1F910-\u1F918\u1F980-\u1F984\u1F9C0]";
text = RemoveEmoji(text, pattern);
// All of the 80 codepoints in the Emoticons block are considered emoji.
// pattern = @"[^\u1F60-\u1F64]";
// text = RemoveEmoji (text, pattern);
// 87 of the 98 codepoints in the Transport and Map Symbols block are considered emoji.
// pattern = @"[^\u1F68-\u1F6F]";
// text = RemoveEmoji (text, pattern);
// 77 of the 256 codepoints in the Miscellaneous Symbols block are considered emoji.
// pattern = @"[^\u260-\u26F]";
// text = RemoveEmoji (text, pattern);
// 77 of the 256 codepoints in the Miscellaneous Symbols block are considered emoji.
// pattern = @"[^\u270-\u27B]";
// text = RemoveEmoji (text, pattern);
return text;
}
static string RemoveEmoji(string text, string pattern)
{
return System.Text.RegularExpressions.Regex.Replace(text, pattern, string.Empty);
}
public static void AmendBuildingRotation(Transform building)
{
var vr = building.localEulerAngles;
vr.y %= 360;
if (vr.y < 0)
{
vr.y += 360;
}
if (vr.y <= 45)
{
vr.y = 0;
}
else if (vr.y <= 135)
{
vr.y = 90;
}
else if (vr.y <= 225)
{
vr.y = 180;
}
else if (vr.y <= 315)
{
vr.y = 270;
}
else
{
vr.y = 0;
}
building.localRotation = Quaternion.Euler(vr);
}
public static long TotalSeconds()
{
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
return Convert.ToInt64(ts.TotalSeconds);
}
public static long TotalMilliseconds()
{
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
return Convert.ToInt64(ts.TotalMilliseconds);
}
public static double Countdown(DateTime dt)
{
TimeSpan ts = (dt - DateTime.UtcNow);
return ts.TotalSeconds;
}
public static double Countdown(long seconds)
{
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
return seconds - ts.TotalSeconds;
}
public static DateTime ParseTime(long seconds)
{
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return dt.AddSeconds(seconds);
}
public static DateTime ParseTimeMilliSecond(long milliseconds)
{
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return dt.AddMilliseconds(milliseconds);
}
public static DateTime ParseTimeFromNow(long countdown)
{
return DateTime.UtcNow.AddSeconds(countdown);
}
public static DateTime NowTime()
{
return DateTime.UtcNow;
}
public static double PastTime(DateTime pastTime)
{
TimeSpan ts = (DateTime.UtcNow - pastTime);
return ts.TotalSeconds;
}
public static int GetDayBySeconds(long seconds)
{
return (int)Mathf.Floor(seconds / (3600 * 24));
}
public static bool IsSameDay(long seconds1, long seconds2)
{
return GetDayInterval(seconds1, seconds2) == 0;
}
public static int GetDayInterval(long seconds1, long seconds2)
{
int day1 = GetDayBySeconds(seconds1);
int day2 = GetDayBySeconds(seconds2);
return Mathf.Abs(day1 - day2);
}
//获取第二天凌晨时间戳
public static long GetTomorrowTimestamp()
{
DateTime tomorrow = DateTime.UtcNow.AddDays(1);
DateTime tomorrowMidnight = new DateTime(tomorrow.Year, tomorrow.Month, tomorrow.Day, 0, 0, 0, 0, DateTimeKind.Utc);
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan diff = tomorrowMidnight.ToUniversalTime() - origin;
return (long)Math.Floor(diff.TotalSeconds);
}
public static string GetDateString()
{
return DateTime.Now.ToString();
}
/// <summary>
/// 获取一个随机列表
/// </summary>
/// <param name="beginInt"></param>
/// <param name="endInt"></param>
/// <returns></returns>
public static IList<int> GetRandomList(int beginInt, int endInt)
{
int count = endInt - beginInt + 1;
IList<int> arr = new int[count];
for (int i = 0; i < count; i++)
{
arr[i] = beginInt + i;
}
Shuffle(arr);
return arr;
}
/// <summary>
/// Array to string. split with ,
/// </summary>
/// <returns>formatted string.</returns>
/// <param name="array">Array.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public static string ArrayToString<T>(T[] array)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
if (array != null && array.Length > 0)
{
for (int i = 0; i < array.Length; i++)
{
if (i != 0)
{
sb.Append(',');
}
sb.Append(array[i]);
}
}
return sb.ToString();
}
/// <summary>
/// 获取当前时间戳(毫秒)
/// </summary>
/// <returns></returns>
public static long GetTimeStamp()
{
// DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
DateTime startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local);// 当地时区
return (long)(DateTime.Now - startTime).TotalMilliseconds;
}
/// <summary>
/// 获取指定时间的时间戳(毫秒)
/// </summary>
/// <returns></returns>
public static long GetTimeStamp(DateTime date)
{
DateTime startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1),
date.Kind == DateTimeKind.Utc ? TimeZoneInfo.Utc : TimeZoneInfo.Local);
return (long)(date - startTime).TotalMilliseconds;
}
/// <summary>
/// 获取当前时间戳(秒)
/// </summary>
/// <returns></returns>
public static long GetTimeStampSeconds()
{
DateTime startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local);// 当地时区
return (long)(DateTime.Now - startTime).TotalSeconds;
}
public static string GetTimeString(string format, int seconds)
{
string label = format;
int ms = seconds * 1000;
int s = seconds;
int m = s / 60;
int h = m / 60;
int d = h / 24;
string t = "";
//处理天
if (label.Contains("%dd"))
{
t = d >= 10 ? d.ToString() : ("0" + d.ToString());
label = label.Replace("%dd", t);
h = h % 24;
}
else if (label.Contains("%d"))
{
label = label.Replace("%d", d.ToString());
h = h % 24;
}
//处理小时
if (label.Contains("%hh"))
{
t = h >= 10 ? h.ToString() : ("0" + h.ToString());
label = label.Replace("%hh", t);
m = m % 60;
}
else if (label.Contains("%h"))
{
label = label.Replace("%h", h.ToString());
m = m % 60;
}
//处理分
if (label.Contains("%mm"))
{
t = m >= 10 ? m.ToString() : ("0" + m.ToString());
label = label.Replace("%mm", t);
s = s % 60;
}
else if (label.Contains("%m"))
{
label = label.Replace("%m", m.ToString());
s = s % 60;
}
//处理秒
if (label.Contains("%ss"))
{
t = s >= 10 ? s.ToString() : ("0" + s.ToString());
label = label.Replace("%ss", t);
ms = ms % 1000;
}
else if (label.Contains("%s"))
{
label = label.Replace("%s", s.ToString());
ms = ms % 1000;
}
//处理毫秒
if (label.Contains("ms"))
{
t = ms.ToString();
label = label.Replace("%ms", t);
}
return label;
}
// 把一个记录的时间戳转换成日期显示(毫秒)
public static string GetTimeStampDateString(double timeStamp, string format = "yyyy-MM-dd HH:mm:ss")
{
// var offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
var offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
var dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Add(offset).AddMilliseconds(timeStamp);
return dt.ToString(format);
}
public static T ArrayFind<T>(T[] array, Predicate<T> condition)
{
T item = default(T);
if (array != null && array.Length > 0)
{
for (int i = 0; i < array.Length; i++)
{
if (condition(array[i]))
{
item = array[i];
break;
}
}
}
return item;
}
public static int ArrayFindIndex<T>(T[] array, Predicate<T> condition)
{
int index = -1;
if (array != null && array.Length > 0)
{
for (int i = 0; i < array.Length; i++)
{
if (condition(array[i]))
{
index = i;
break;
}
}
}
return index;
}
public static T[] ArrayAdd<T>(T[] array, T item)
{
List<T> newArray = new List<T>();
if (array != null)
{
newArray.AddRange(array);
}
newArray.Add(item);
return newArray.ToArray();
}
public static int RandomByWeight(Dictionary<int, int> idWeights)
{
int weights = 0;
int id = 0;
foreach (var kv in idWeights)
{
weights += kv.Value;
id = kv.Key;
}
int pos = UnityEngine.Random.Range(0, weights);
weights = 0;
foreach (var kv in idWeights)
{
weights += kv.Value;
if (pos < weights)
{
id = kv.Key;
break;
}
}
return id;
}
public static int RandomByWeight(List<int> weightList)
{
int weights = 0;
int idx = 0;
for (int i = 0; i < weightList.Count; i++)
{
weights += weightList[i];
}
int pos = UnityEngine.Random.Range(0, weights);
weights = 0;
for (int i = 0; i < weightList.Count; i++)
{
weights += weightList[i];
if (pos < weights)
{
idx = i;
break;
}
}
return idx;
}
public static int RandomByWeight(int[] weightList)
{
int weights = 0;
int idx = 0;
for (int i = 0; i < weightList.Length; i++)
{
weights += weightList[i];
}
int pos = UnityEngine.Random.Range(0, weights);
weights = 0;
for (int i = 0; i < weightList.Length; i++)
{
weights += weightList[i];
if (pos < weights)
{
idx = i;
break;
}
}
return idx;
}
public static void JumpToAnimation(Animator animator, string stateName, float normalizedTime, int layer = -1)
{
animator.Play(stateName, layer, normalizedTime);
}
public static string GetLevelDisplay(int levelId)
{
//潜规则策划修改为301 - 但需要显示为1
int lv = levelId % 100;
return lv.ToString();
}
/// <summary>
/// Gets the ADIDB y platform async.
/// </summary>
/// <param name="callback">Application.AdvertisingIdentifierCallback回调参数一共有三string adid bool 是否成功 string error.</param>
public static void GetADIDByPlatformAsync(Application.AdvertisingIdentifierCallback callback)
{
Application.RequestAdvertisingIdentifierAsync(callback);
}
public static string PlayerIdToString(ulong playerId)
{
return (playerId + 0xb2c3d4).ToString("x");
}
public static ulong StringToPlayerId(string str)
{
ulong playerId = Convert.ToUInt64(str, 16);
playerId -= 0xb2c3d4;
return playerId;
}
public static void SaveToLocal(string key, string data)
{
byte[] encryptData = RijndaelManager.Instance.EncryptStringToBytes(data);
PlayerPrefs.SetString(key, System.Convert.ToBase64String(encryptData));
}
public static string ReadFromLocal(string key, string defaultData = "")
{
if (PlayerPrefs.HasKey(key))
{
byte[] encryptData = System.Convert.FromBase64String(PlayerPrefs.GetString(key));
defaultData = RijndaelManager.Instance.DecryptStringFromBytes(encryptData);
}
return defaultData;
}
public static NameValueCollection ParseQueryString(string s)
{
NameValueCollection nvc = new NameValueCollection();
// remove anything other than query string from url
if (s.Contains("?"))
{
s = s.Substring(s.IndexOf('?') + 1);
}
foreach (string vp in Regex.Split(s, "&"))
{
DebugUtil.Log("vp = {0}", vp);
string[] singlePair = Regex.Split(vp, "=");
if (singlePair.Length == 2)
{
DebugUtil.Log("key = {0} value = {1}", singlePair[0], singlePair[1]);
nvc.Add(singlePair[0], singlePair[1]);
}
else
{
DebugUtil.Log("key = {0} value = null", singlePair[0]);
// only one key with no value specified in query string
nvc.Add(singlePair[0], string.Empty);
}
}
return nvc;
}
public static string GetMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
/// <summary>
/// 判断是否是磁盘空间已满异常
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
public static bool IsDiskFull(Exception ex)
{
if (ex == null)
{
return false;
}
const int HR_ERROR_HANDLE_DISK_FULL = unchecked((int)0x80070027);
const int HR_ERROR_DISK_FULL = unchecked((int)0x80070070);
return ex.HResult == HR_ERROR_HANDLE_DISK_FULL
|| ex.HResult == HR_ERROR_DISK_FULL;
}
/// <summary>
/// 格式化json
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ConvertJsonString(string str)
{
JsonSerializer serializer = new JsonSerializer();
TextReader tr = new StringReader(str);
JsonTextReader jtr = new JsonTextReader(tr);
object obj = serializer.Deserialize(jtr);
if (obj != null)
{
StringWriter textWriter = new StringWriter();
JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
{
Formatting = Formatting.Indented,
Indentation = 4,
IndentChar = ' '
};
serializer.Serialize(jsonWriter, obj);
return textWriter.ToString();
}
else
{
return str;
}
}
/// <summary>
/// 将秒转化为x小时x分x秒格式
/// </summary>
/// <param name="seconds"></param>
/// <returns></returns>
/// <returns></returns>
public static string GetTimeDescStr(int seconds)
{
string retStr = "";
int h = seconds / 3600;
int m = (seconds - h * 3600) / 60;
int s = seconds - h * 3600 - m * 60;
if (h > 0)
{
if (s > 0)
{
retStr = GetLocalizeText("time_hour_min_sec", h, m, s);
}
else if (m > 0)
{
retStr = GetLocalizeText("time_hour_min", h, m);
}
else
{
retStr = GetLocalizeText("time_hour", h);
}
}
else
{
if (m > 0)
{
if (s > 0)
{
retStr = GetLocalizeText("time_min_sec", m, s);
}
else
{
retStr = GetLocalizeText("time_min", m);
}
}
else
{
retStr = GetLocalizeText("time_sec", s);
}
}
return retStr;
}
//转换为英文缩写
public static string NumToEnglish(uint value)
{
if (value > 10000 && value <= 10000000)
{
return string.Format("{0}K", (value / 1000).ToString());
}
else if (value > 10000000)
{
return string.Format("{0}M", (value / 1000000).ToString());
}
else
{
return value.ToString();
}
}
public static float CheckAngle(float value)
{
float angle = value - 180;
if (angle > 0)
return angle - 180;
return angle + 180;
}
public static int GetTransformIndex(Transform transform)
{
var parent = transform.parent;
if (parent != null)
{
var childCount = parent.childCount;
for (int i = 0; i < childCount; i++)
{
var child = parent.GetChild(i);
if (child == transform)
return i;
}
}
return -1;
}
public static void PreLoadOrUnloadEnvironmentWeatherDayNightIcon(bool loadOrUnload)
{
List<string> paths = new();
foreach (var value in Enum.GetValues(typeof(MapData.EnvironmentType)))
{
var enumValue = (MapData.EnvironmentType)value;
var config = GetEnvironmentConfig(enumValue);
paths.Add(config.Icon);
}
foreach (var value in Enum.GetValues(typeof(LevelData.WeatherType)))
{
var enumValue = (LevelData.WeatherType)value;
var config = GetWeatherConfig(enumValue);
paths.Add(config.Icon);
}
foreach (var value in Enum.GetValues(typeof(LevelData.DayNightType)))
{
var enumValue = (LevelData.DayNightType)value;
var config = GetDayNightConfig(enumValue);
paths.Add(config.Icon);
}
foreach (var iconPath in paths)
{
if(loadOrUnload)
AssetManager.Instance.PostPreload<Sprite>(iconPath);
else
AssetManager.Instance.Unload(iconPath);
}
}
public static DataEnWeather GetWeatherConfig(LevelData.WeatherType weatherType)
{
var result = TableManager.Instance.Tables.WeatherConfig.Get((int)weatherType);
return result;
}
public static DataEnviorment GetEnvironmentConfig(MapData.EnvironmentType environmentType)
{
var result = TableManager.Instance.Tables.EnviormentConfig.Get((int)environmentType);
return result;
}
public static DataDayNightProp GetDayNightConfig(LevelData.DayNightType dayNightType)
{
var result = TableManager.Instance.Tables.DayNightProp.Get((int)dayNightType);
return result;
}
public static void AddItem(ref List<cfg.item.ItemCounts> sumItem, cfg.item.ItemCounts item1)
{
for (int i = 0; i < sumItem.Count; i++)
{
if (sumItem[i].Id==item1.Id)
{
sumItem[i]=new cfg.item.ItemCounts(sumItem[i].Id, sumItem[i].Count+item1.Count);
return;
}
}
sumItem.Add(item1);
}
public static cfg.item.ItemCounts ItemXNumber(cfg.item.ItemCounts item,int number)
{
return new cfg.item.ItemCounts(item.Id, item.Count * number);
}
public static string GetVehicleBonusStr(BonusType btype)
{
switch (btype)
{
case BonusType.Hp:
return GetLocalizeText("cultivate_Hp");
case BonusType.SkillLv:
return GetLocalizeText("vehicleCultivate_skillLv");
case BonusType.MoveSpeed:
return GetLocalizeText("cultivate_Speed");
case BonusType.SeatCount:
return GetLocalizeText("vehicleCultivate_PersonNum");
}
return "";
}
public static void ShowMessageTips(string TipsMsg)
{
UITipsManager.ShowTips(TipsMsg);
}
public static void SetActive(GameObject obj,bool isActive)
{
if(isActive)
{
obj.transform.localScale = Vector3.one;
}else
{
obj.transform.localScale = Vector3.zero;
}
}
// /// <summary>
// /// 要保证所有网格能对齐,需要调整网格的列数和行数,规则是column必须是偶数row必须是偶数且必须是奇数的两倍
// /// 这样能保证网格一定对齐
// /// </summary>
// /// <param name="columnAndRow"></param>
// /// <returns></returns>
// public static void CorrectTGSColumnAndRow(ref int column, ref int row)
// {
// if (column % 2 != 0)
// {
// column--;
// }
//
// var halfRow = row / 2;
// if (halfRow % 2 == 0)
// {
// halfRow++;
// }
//
// row = halfRow * 2;
// }
/// <summary>
/// 获得Tgs中长度对应的六边形数量
/// </summary>
/// <param name="totalLength">总长度</param>
/// <param name="hexDiagonalLength">六边形对角线长度</param>
/// <param name="isDiagonal">是否对角线朝向排列</param>
/// <returns></returns>
public static int GetHexCount(float totalLength, float hexDiagonalLength, bool isDiagonal)
{
if (isDiagonal)
return Mathf.FloorToInt((4 * totalLength) / (3 * hexDiagonalLength) - 1 / 3f);
else
{
var sqrt3 = Mathf.Sqrt(3);
var countInFloat = (totalLength - (sqrt3 / 4 * hexDiagonalLength)) /
(Mathf.Sqrt(3) / 2 * hexDiagonalLength);
return Mathf.FloorToInt(countInFloat);
}
}
public static bool IsInGame()
{
return Application.isPlaying && Object.FindObjectOfType<Main>() != null;
}
/// <summary>
/// 设置uint的某一位返回int
/// </summary>
/// <param name="data">被设置的数据</param>
/// <param name="idx">第idx位</param>
/// <param name="flag">true为0 false为1</param>
public static int GetIntBitByIndex(uint data, int idx, bool flag)
{
if (idx > 31 || idx < 0)
{
return (int)data;
}
if (!flag)
{
data |= (uint)(1 << idx);
}
else
{
data &= ~(uint)(1 << idx);
}
return (int)data;
}
public static string GetItemDisPlayName(int id)
{
DataItem itemcfg = TableManager.Instance.Tables.Item.Get(id);
if(itemcfg==null)
{
DebugUtil.LogError("该物体不存在:" + id);
return "";
}
return "";//等配置,延后
}
/// <summary>
/// 随机抽取
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="removeItem"></param>
/// <returns></returns>
public static T GetRandomItem<T>(IList<T> list, bool removeItem = false)
{
if (list == null || list.Count == 0)
return default;
int randomIndex = Random.Range(0, list.Count);
T result = list[randomIndex];
if (removeItem)
list.RemoveAt(randomIndex);
return result;
}
/// <summary>
/// 随机不重复的取一定数量的物体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">全部物体序列</param>
/// <param name="count">要取的数量</param>
/// <returns></returns>
public static T[] GetRandomItems<T>(IList<T> list, int count)
{
if (list == null)
{
DebugUtil.LogError("空数据");
return null;
}
if (list.Count < count)
{
DebugUtil.LogError("数量错误");
return null;
}
if (count <= 0)
return new T[0];
IList<T> listValue = new T[count];
Shuffle(list);
for (int i = 0; i < listValue.Count; ++i)
{
listValue[i] = list[i];
}
return (T[])listValue;
}
/// <summary>
/// 洗牌算法打乱顺序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static void Shuffle<T>(IList<T> list)
{
if (list == null)
{
DebugUtil.LogError("空数据");
return;
}
for (int i = list.Count - 1; i >= 0; --i)
{
int index = Random.Range(0, i + 1);
if (index == i)
continue;
(list[index], list[i]) = (list[i], list[index]);
}
}
public static T GetSceneRootComponent<T>(Scene scene) where T : Component
{
return scene.GetRootGameObjects().FirstOrDefault(root => root.GetComponent<T>() != null)?.GetComponent<T>();
}
public class UISceneResult
{
public UIWindow uiWindow { get; private set; }
public SceneHandle sceneHandle{ get; private set; }
public UISceneResult(UIWindow uiWindow, SceneHandle sceneHandle)
{
this.uiWindow = uiWindow;
this.sceneHandle = sceneHandle;
}
}
/// <summary>
/// 打开带场景的UI,此函数会处理多场景渲染和主相机逻辑
/// 必须和CloseUIWithScene成对使用
/// </summary>
/// <param name="uiName"></param>
/// <param name="scenePath"></param>
/// <param name="uiParam"></param>
/// <param name="openLoadingUI">是否先打开加载UI</param>
/// <param name="loadSceneFinish">加载场景结束后加载UI前的回调</param>
/// <returns></returns>
public static async UniTask<UISceneResult> OpenUIWithScene(string uiName, string scenePath,
object uiParam = null, bool openLoadingUI = true,LoadSceneMode loadSceneMode = LoadSceneMode.Additive,
Action<SceneHandle> loadSceneFinish = null)
{
//隐藏上层UI
UIManager.Instance.HideAllUI(UINameConst.UI_Loading);
//先加载场景
if (openLoadingUI)
{
//如果要打开加载UI
var loadingExecutor = new LoadingExecutorWithUILoadingController();
loadingExecutor.getProgress = () => GameSceneManager.Instance.GetSceneLoadingProgress(scenePath);
LoadingExecutorManager.Instance.ExecuteLoading(loadingExecutor);
}
var sceneHandle = await GameSceneHelper.Instance.LoadSceneForUIView(scenePath, loadSceneMode);
if (sceneHandle == null)
{
DebugUtil.LogError($"加载场景失败!scenePath:{scenePath}");
return null;
}
loadSceneFinish?.Invoke(sceneHandle);
//加载UI
var window = await UIManager.Instance.OpenWindow(uiName);
return new UISceneResult(window, sceneHandle);
}
//关闭带场景的UI
//必须和OpenUIWithScene成对使用
public static async UniTask CloseUIWithScene(string uiName)
{
await GameSceneHelper.Instance.UnloadSceneForUIView();
UIManager.Instance.CloseWindow(uiName);
UIManager.Instance.ShowAllUI();
}
public static void SetImageGrayByChangeColor(Image image,bool isGray)
{
if(isGray)
{
image.color = new Color((float)156 / (float)255, (float)156 / (float)255, (float)155 / (float)255);
}else
{
image.color = new Color(1, 1, 1);
}
}
}
}