using Assets.Scripts.UI.Control;
using DG.Tweening;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
namespace Assets.Scripts
{
public static class Utils
{
/*获取ip*/
public enum ADDRESSFAM
{
IPv4, IPv6
}
///
/// 获取本机IP
///
/// 要获取的IP类型
///
public static string GetIP(ADDRESSFAM Addfam)
{
if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
{
return null;
}
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
#endif
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
//IPv4
if (Addfam == ADDRESSFAM.IPv4)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
//Debug.Log("IP:" + output);
}
}
//IPv6
else if (Addfam == ADDRESSFAM.IPv6)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
output = ip.Address.ToString();
}
}
}
}
}
return output;
}
///
///
///
///
/// 直接输入面板坐标即可
///
public static Vector3 GetTruePosition(this Transform rect, Vector2 point)
{
if (!rect.parent) return point;
RectTransform myRect = rect.GetComponent()
,prect = rect.parent.GetComponent();
return new Vector2(point.x + prect.sizeDelta.x * (myRect.pivot.x - prect.pivot.x), point.y + prect.sizeDelta.y * (myRect.pivot.y - prect.pivot.y));
}
public static bool isPointInTransfrom(this RectTransform rect,Vector2 point)
{
var MainCanvas = UIManager.Instance.MainCanvas;
if (!MainCanvas) return false;
var size = rect.sizeDelta * MainCanvas.transform.localScale;
var sPoint = new Vector2(rect.position.x - rect.pivot.x * size.x, rect.position.y - rect.pivot.y * size.y);
var ePoint = new Vector2(rect.position.x + (1 - rect.pivot.x) * size.x, rect.position.y + (1 - rect.pivot.y) * size.y);
return point.x >= sPoint.x && point.x <= ePoint.x && point.y >= sPoint.y && point.y <= ePoint.y;
}
public static bool isLowIPhone()
{
var info = SystemInfo.deviceModel;
if (info.Contains("iPhone"))
{
//iPhone2,1
var s = info.Replace("iPhone", "").Split(',');
return s.Length == 2 && int.TryParse(s[0],out int gen) && gen < 9;
}
return false;
}
/*获取ip*/
/*显示简略提示,需要拖Toast的预制件,且保证其他组件名字不是Toast,ToastContainer*/
private static Dictionary _toastDict;
private static Dictionary toastDict
{
get
{
if (_toastDict == null)
{
_toastDict = new Dictionary
{
{0,"Images/home/wrong|#f93086" },{1,"Images/home/right|#41A6FE" }
};
}
return _toastDict;
}
set
{
_toastDict = value;
}
}
private static Dictionary _deviceDict;
public static Dictionary deviceDict
{
get
{
if (_deviceDict == null)
{
_deviceDict = new Dictionary
{
{"Trainer","Smart Trainer|Images/Devices/Trainer_3" },
{"Power","Power Meter|Images/Devices/Power_3" },
{"Cadence","Cadence Sensor|Images/Devices/Cadence_3" },
{"HeartRate","Heart Rate Monitor|Images/Devices/Heart Rate_3" },
{"SpeedCadence","Cadence Sensor|Images/Devices/Cadence_3" },
{"Speed","Speed Meter|Images/Devices/Speed_3" },
{"Rower","Rower Machine|Images/Rower/设备 - 划船机" }
};
}
return _deviceDict;
}
private set
{
_deviceDict = value;
}
}
///
///
///
///
///
///
/// 0 错误 1 正确
///
///
///
///
///
public static void showToast(GameObject p, string text, int duration = 2, int type = 0, Func stopFunc = null, bool isLowest = false,bool showSeconds = false,Action endCallback = null,PFUIPanel _parent = null)
{
var parent = UIManager.Instance.ModalsPanel;
if (parent == null)
{
if (_parent)
{
parent = _parent;
}
else
{
return;
}
}
if (!parent.gameObject.activeInHierarchy) parent.gameObject.SetActive(true);
var toast = parent.transform.Find("ToastContainer");
if (toast != null)
{
MonoBehaviour.DestroyImmediate(toast.gameObject);
}
#if UNITY_IOS || UNITY_ANDROID
var newToast = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/ToastContainer-mobile"));
#else
var newToast = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/ToastContainer"));
#endif
newToast.name = "ToastContainer";
newToast.GetComponent().position = new Vector3(Screen.width / 2, Screen.height / 2, 0);
newToast.transform.parent = parent.transform;
toast = newToast.transform;
var toastStyle = toastDict[type].Split('|');
if (isLowest)
{
toast.SetAsFirstSibling();
}
else
{
toast.SetAsLastSibling();
}
toast.Find("Image").GetComponent().sprite = Resources.Load(toastStyle[0]);
toast.GetComponent().color = HexToColorHtml(toastStyle[1]);
toast.GetComponent().showToast(new ToastParams
{
text = text,
duration = duration,
func = stopFunc,
showSeconds = showSeconds,
endCallback = endCallback
});
}
public class ToastParams
{
public bool showSeconds { get; set; }
public string text { get; set; }
public int duration { get; set; }
public Func func { get; set; }
public Action endCallback { get; set; }
}
/*显示简略提示,需要拖Toast的预制件,且保证其他组件名字不是Toast,ToastContainer*/
public static void showLoading(this GameObject game)
{
var parent = Utils.FindUpParent(game.transform);
var loading = parent.Find("Loading");
if (loading == null)
{
#if UNITY_IOS || UNITY_ANDROID
var newLoading = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/Common/Mobile/Loading"));
#else
var newLoading = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/Common/Loading"));
#endif
newLoading.name = "Loading";
newLoading.GetComponent().position = new Vector3(Screen.width / 2, Screen.height / 2, 0);
newLoading.transform.parent = parent;
loading = newLoading.transform;
}
loading.GetComponent().Show();
}
public static bool isUpdate(string currentVersion,string realVersion)
{
var a = currentVersion.Split('.');
var b = realVersion.Split('.');
if (a.Length != 3 || b.Length != 3) return false;
for (int i = 0; i < 3; i++)
{
var f1 = int.TryParse(a[i], out int ai);
var f2 = int.TryParse(b[i], out int bi);
if (!f1 || !f2) return false;
if (ai < bi)
{
return true;
}
else if (ai > bi)
{
return false;
}
}
return false;
}
public static void CallAndroidMethod(string methodName,params object[] args)
{
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = jc.GetStatic("currentActivity");
activity.Call(methodName, args);
#endif
}
public static void showLoadingExtension(this GameObject game)
{
game.SetActive(true);
var loading = game.transform.Find("Loading");
if (loading == null)
{
#if UNITY_IOS || UNITY_ANDROID
var newLoading = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/Common/Mobile/Loading"));
#else
var newLoading = MonoBehaviour.Instantiate(Resources.Load("UI/Prefab/Common/Loading"));
#endif
newLoading.name = "Loading";
newLoading.GetComponent().position = new Vector3(Screen.width / 2, Screen.height / 2, 0);
newLoading.transform.SetParent(game.transform);
loading = newLoading.transform;
loading.localScale = new Vector3(1, 1, 1);
}
loading.GetComponent().Show();
}
public static void hideLoadingExtension(this GameObject game)
{
var loading = game.transform.Find("Loading");
if (loading != null)
{
loading.GetComponent().Close();
}
game.SetActive(false);
}
public static void hideLoading(this GameObject game)
{
var parent = Utils.FindUpParent(game.transform);
var loading = parent.Find("Loading");
if (loading != null)
{
//loading.gameObject.SetActive(false);
loading.GetComponent().Close();
}
}
/*删除父亲节点下的所有孩子*/
static public void DestroyChildren(this Transform t,string igNoreName = null)
{
bool isPlaying = Application.isPlaying;
while (t.childCount != 0)
{
Transform child = t.GetChild(0);
if (isPlaying)
{
child.SetParent(null);
UnityEngine.Object.Destroy(child.gameObject);
}
else UnityEngine.Object.DestroyImmediate(child.gameObject);
}
Resources.UnloadUnusedAssets();
GC.Collect();
}
/*删除父亲节点下的所有孩子*/
/*显示网络图片*/
public static void GetImageBytes(string url, Action p)
{
if (string.IsNullOrEmpty(url))
return;
UIManager.Instance.StartCoroutine(DownloadImageByte(url, p));
}
public static Dictionary propTextureCache = new Dictionary();
public delegate Coroutine StartCoroutine(IEnumerator routine);
public static void DisplayImage(MaskableGraphic img, string url, bool cache = false,Dictionary caches = null)
{
if (string.IsNullOrEmpty(url))
return;
//可以考虑缓存到硬盘里
//Texture2D tex = null;
//byte[] fileData;
//
//if (File.Exists(filePath))
//{
// fileData = File.ReadAllBytes(filePath);
// tex = new Texture2D(2, 2);
// tex.LoadImage(fileData); //..this will auto-resize the texture dimensions.
//}
if (cache)
{
if (propTextureCache.ContainsKey(url))
{
var texture = propTextureCache[url];
if (img.GetComponent())
{
img.GetComponent().texture = texture;
}
else if (img.GetComponent())
{
img.GetComponent().ShowImageWithTexture(texture);
}
return;
}
}
UIManager.Instance.StartCoroutine(DownloadImage(img, url,(texture)=> {
if (cache && !propTextureCache.ContainsKey(url))
{
propTextureCache.Add(url, texture);
}
}));
}
///
/// 使用临时字典存放图片,切换页面后清除
///
///
///
///
public static void DisplayImageTempDict(MaskableGraphic img, string url, Dictionary caches = null,UnityAction callback = null)
{
if (string.IsNullOrEmpty(url))
return;
if (caches!=null)
{
if (caches.ContainsKey(url))
{
var texture = caches[url];
if (img.GetComponent())
{
img.GetComponent().texture = texture;
}
else if (img.GetComponent())
{
img.GetComponent().ShowImageWithTexture(texture);
}
if (callback != null)
{
callback.Invoke(null);
}
return;
}
}
UIManager.Instance.StartCoroutine(DownloadImage(img, url, (texture) => {
if (caches != null && !caches.ContainsKey(url))
{
caches.Add(url, texture);
}
},callback));
}
public static void DisplayImageAysnc(StartCoroutine startCoroutine, RawImage img, string url,Action action)
{
startCoroutine(DownloadImageCallBack(img, url, action));
}
static IEnumerator DownloadImageByte(string MediaUrl, Action action = null)
{
UnityWebRequest request = UnityWebRequest.Get(MediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
action.Invoke(null);
}
else
{
if (action != null)
{
action.Invoke(request.downloadHandler.data);
}
}
}
static IEnumerator DownloadImage(MaskableGraphic img,string MediaUrl, Action action = null,UnityAction callback = null)
{
UnityWebRequest request = UnityWebRequest.Get(MediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
Debug.Log(request.error);
else if (img != null)
{
var data = request.downloadHandler.data;
var texture = Utils.GetDownloadTexture(MediaUrl, data);
if (img.GetComponent())
{
img.GetComponent().texture = texture;
}
else if(img.GetComponent())
{
img.GetComponent().ShowImageWithTexture(texture);
}
if (action != null)
{
action.Invoke(texture);
}
if (callback != null)
{
callback.Invoke(data);
}
}
}
public static Texture GetDownloadTexture(string MediaUrl, byte[] data)
{
#if UNITY_EDITOR
var _t = new Texture2D(4, 4, TextureFormat.DXT5, false);
#else
#if UNITY_IOS
var _t = new Texture2D(4, 4, TextureFormat.ASTC_RGB_4x4,false);
Debug.Log("使用了壓縮");
#elif UNITY_ANDROID
var _t = new Texture2D(4, 4, TextureFormat.ASTC_RGB_4x4,false);
Debug.Log("使用了壓縮");
#else //pc
var _t = new Texture2D(4, 4, TextureFormat.DXT5,false);
#endif
#endif
_t.LoadImage(data,true);
_t.name = MediaUrl;
return _t;
}
static IEnumerator DownloadImageCallBack(RawImage img, string MediaUrl,Action action)
{
UnityWebRequest request = UnityWebRequest.Get(MediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
Debug.Log(request.error);
else
{
var data = request.downloadHandler.data;
img.texture = Utils.GetDownloadTexture(MediaUrl, data);
action.Invoke(MediaUrl, img);
}
}
/*显示网络图片*/
/*获取最顶层对象*/
public static Transform FindUpParent(Transform zi)
{
if (zi.parent == null)
return zi;
else
return FindUpParent(zi.parent);
}
/*获取最顶层对象*/
/*Texture相关*/
public static Texture2D DeCompress(this Texture2D source)
{
RenderTexture renderTex = RenderTexture.GetTemporary(
source.width,
source.height,
0,
RenderTextureFormat.Default,
RenderTextureReadWrite.Linear);
Graphics.Blit(source, renderTex);
RenderTexture previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D readableText = new Texture2D(source.width, source.height);
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
readableText.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTex);
return readableText;
}
public static void WriteTextureToPlayerPrefs(string tag, Texture2D tex)
{
// if texture is png otherwise you can use tex.EncodeToJPG().
byte[] texByte = tex.DeCompress().EncodeToJPG();
// convert byte array to base64 string
string base64Tex = System.Convert.ToBase64String(texByte);
// write string to playerpref
PlayerPrefs.SetString(tag, base64Tex);
PlayerPrefs.Save();
}
public static Texture2D ReadTextureFromPlayerPrefs(string tag)
{
// load string from playerpref
string base64Tex = PlayerPrefs.GetString(tag, null);
if (!string.IsNullOrEmpty(base64Tex))
{
// convert it to byte array
byte[] texByte = System.Convert.FromBase64String(base64Tex);
#if UNITY_ANDROID || UNITY_IOS
Texture2D tex = new Texture2D(4, 4, TextureFormat.ASTC_RGB_4x4,false);
#else
Texture2D tex = new Texture2D(4, 4, TextureFormat.DXT5,false);
#endif
//load texture from byte array
if (tex.LoadImage(texByte))
{
return tex;
}
}
return null;
}
/*Texture相关*/
public static byte[] StreamToBytes(Stream stream)
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
return bytes;
}
public static Color HexToColor(string hex)
{
byte r = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
byte b = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
return new Color32(r, g, b, byte.MaxValue);
}
public static Color HexToColorHtml(string hex)
{
ColorUtility.TryParseHtmlString(hex, out Color c);
return c;
}
///
/// Generate random digit code
///
/// Length
/// Result string
public static string GenerateRandomDigitCode(int length)
{
var random = new System.Random();
string str = string.Empty;
for (int i = 0; i < length; i++)
str = String.Concat(str, random.Next(10).ToString());
return str;
}
/*文件转精灵*/
public static Sprite PngToSprite(string fullPath, int x, int y)
{
using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read)) //自动双清
{
fs.Seek(0, SeekOrigin.Begin); //设定当前流的位置
byte[] bytes = new byte[fs.Length]; //创建文件长度缓冲区
fs.Read(bytes, 0, (int)fs.Length); //读取文件
Texture2D texture = new Texture2D(x, y); //创建Texture
texture.LoadImage(bytes);
return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one / 2);
}
}
/*文件转精灵*/
/*打开文件*/
public delegate void OpenFileCallBack(string path);
public static void OpenFile(OpenFileCallBack callBack,string filter = null)
{
OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = "Image Files(*.jpg;*.jpeg;*.png;*.bmp)\0*.jpg;*.png;*.jpeg;*.bmp\0";
if (filter != null) ofn.filter = filter;
ofn.file = new string(new char[256]);
ofn.maxFile = ofn.file.Length;
ofn.fileTitle = new string(new char[64]);
ofn.maxFileTitle = ofn.fileTitle.Length;
ofn.initialDir = UnityEngine.Application.dataPath;//默认路径
ofn.title = "Open Project";
ofn.defExt = "JPG";//显示文件的类型
//注意 一下项目不一定要全选 但是0x00000008项不要缺少
ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008;
//0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008 OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR
if (Win32.GetOpenFileName(ofn))
{
callBack(ofn.file);
}
}
/*打开文件*/
/*文本框/下拉框错误*/
public static void SetValidate(Dictionary dict, JArray errorList)
{
if (errorList == null) return;
foreach (var error in errorList)
{
var className = dict[error.Value("Field")].GetType().Name;
if (className == "InputField")
{
dict[error.Value("Field")].GetComponent()
.SetValidate(true);
}
else if (className == "Dropdown")
{
dict[error.Value("Field")].GetComponent()
.SetValidate();
}
//formDict[error.Value("Filed")].error.Value("ErrMsg");
}
}
/*文本框/下拉框错误*/
public static void ExecFile(string path,string args = "")
{
System.Diagnostics.Process proc = null;
try
{
proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = path;
proc.StartInfo.Arguments = args;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.Verb = "runas";
proc.Start();
}
catch (Exception ex)
{
Console.WriteLine("执行批处理的时候出现了异常!");
}
}
/*下载文件*/
public static void DisplayHead(MaskableGraphic raw, string s)
{
if (string.IsNullOrEmpty(s))
{
var t = Resources.Load("Images/icon-1024");
if (raw.GetComponent())
{
raw.GetComponent().texture = Resources.Load("Images/icon-1024");
}
else if (raw.GetComponent())
{
raw.GetComponent().ShowImageWithTexture(t);
}
}
else
{
DisplayImage(raw, s);
}
}
public static void ShowImageWithTexture(this Image img, Texture t)
{
img.sprite = Sprite.Create((Texture2D)t, new Rect(0, 0, t.width, t.height), Vector2.zero);
}
public static void SetTextWithEllipsis(this Text textComponent, string value)
{
var generator = new TextGenerator();
var rectTransform = textComponent.GetComponent();
var settings = textComponent.GetGenerationSettings(rectTransform.rect.size);
generator.Populate(value, settings);
var characterCountVisible = generator.characterCountVisible;
var updatedText = value;
if (value.Length > characterCountVisible && characterCountVisible != -1)
{
updatedText = value.Substring(0, characterCountVisible - 3);
updatedText += "…";
}
textComponent.text = updatedText;
}
public static string GetCountDown(TimeSpan time)
{
var second = Math.Ceiling(time.TotalSeconds);
var ts = TimeSpan.FromSeconds(second);
return $"{ (int)ts.TotalHours }:{ts:mm}:{ts:ss}";
}
private static IEnumerator TimerFunc(float seconds, Action action)
{
while (true)
{
yield return new WaitForSeconds(seconds); // 停止执行1秒
action.Invoke();
//time = UIManager.Now.GetDateTime().AddSeconds(1);
}
}
public static void StartTimeUnLimit(float seconds,Action action)
{
UIManager.Instance.StartCoroutine(TimerFunc(seconds, action));
}
public static void MyDOFade(this Transform transform)
{
var cg = transform.GetComponent();
if (cg)
{
cg.alpha = 0;
#if UNITY_IOS
cg.DOFade(1f, .6f);
#else
cg.DOFade(1f, .3f);
#endif
}
}
public static IEnumerator StartLocation(Action action = null)
{
// Check if the user has location service enabled.
if (!Input.location.isEnabledByUser)
yield break;
// Starts the location service.
Input.location.Start();
// Waits until the location service initializes
int maxWait = 20;
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
{
yield return new WaitForSeconds(1);
maxWait--;
}
// If the service didn't initialize in 20 seconds this cancels location service use.
if (maxWait < 1)
{
Debug.Log("Timed out");
yield break;
}
// If the connection failed this cancels location service use.
if (Input.location.status == LocationServiceStatus.Failed)
{
Debug.Log("Unable to determine device location");
yield break;
}
else
{
// If the connection succeeded, this retrieves the device's current location and displays it in the Console window.
Debug.Log("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
if (action != null)
{
action.Invoke(Input.location.lastData);
}
}
// Stops the location service if there is no need to query location updates continuously.
Input.location.Stop();
}
public static string ToLocalString(this DateTime time, string format)
{
if (App.GetLocalLanguage() == "en")
{
return time.ToString(format);
}
else
{
if(format == "HH:mm:ss dd-MM-yyyy")
return time.ToString("yyyy-MM-dd HH:mm:ss");
else
return time.ToString("yyyy-MM-dd");
}
}
}
}