using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using System.Reflection;
using System.Linq;
public class Ywa_StaticFuns
{
/// <summary>
/// list转化为字符串
/// </summary>
public static string ListToSting<T>(List<T> list,string arg="")
{
var listStr = "";
if (list == null)
{
listStr = null;
} else
{
for (int i = 0; i < list.Count; i++)
{
listStr += list[i].ToString();
if (i + 1 < list.Count)
{
listStr += arg;
}
}
}
return listStr;
}
//添加添加子物体,位置,旋转复位
public static GameObject AddChild(GameObject parent, GameObject prefab)
{
GameObject go = GameObject.Instantiate(prefab) as GameObject;
if (go != null && parent != null)
{
Transform t = go.transform;
t.parent = parent.transform;
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
go.layer = parent.layer;
}
return go;
}
// 获取所有子物体组件
public static List<T> GetInner<T>(GameObject obj)
{
Transform selfTran = obj.transform;
List<T> m_List = new List<T>();
for (int i = 0; i < selfTran.childCount; i++)
{
Transform tran = selfTran.GetChild(i);
T t = tran.GetComponent<T>();
if (t != null)
{
m_List.Add(t);
}
}
return m_List;
}
public static List<GameObject> FindAllChilds(GameObject obj)
{
List<GameObject> m_List = new List<GameObject>();
for (int i = 0; i < obj.transform.childCount; i++)
{
if (obj.transform.GetChild(i).childCount > 0)
{
FindAllChilds(obj.transform.GetChild(i).gameObject);
}
GameObject m_Obj = obj.transform.GetChild(i).gameObject;
m_List.Add(m_Obj);
}
return m_List;
}
//设置gameobject父物体
public static void SetParent(GameObject parent, GameObject childobj)
{
if (childobj != null && parent != null)
{
Transform t = childobj.transform;
t.parent = parent.transform;
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
}
}
//获取多平台streamasset目录
public static string GetStreamAssetPath() => Application.streamingAssetsPath;
//处理表格负号用#代替的问题
public static float ReverseNum(string sNum)
{
if (sNum.Contains("#"))
{
sNum = sNum.Replace("#", "");
return -float.Parse(sNum);
} else
{
return float.Parse(sNum);
}
}
public static T FindInChild<T>(GameObject parent, string findname, bool containDeactiveobj = true) where T : Component
{
if (string.IsNullOrEmpty(findname)) { return default(T); }
string[] nameArr = findname.Split('/');
for (int i = 0; parent != null && i < nameArr.Length; i++)
{
if (i == nameArr.Length - 1)
{
T[] arr = parent.GetComponentsInChildren<T>(containDeactiveobj);
foreach (T t in arr)
{
if (t.name.Equals(nameArr[i])) { return t; }
}
}
else
{
parent = FindInChild(parent, nameArr[i], containDeactiveobj);
}
}
return default(T);
}
//根据名字查找子物体
public static GameObject FindInChild(GameObject parent, string findname, bool containDeactiveobj = true) => FindInChild<Transform>(parent, findname, containDeactiveobj)?.gameObject;
//根据名字查找所有子物体
public static GameObject[] FindAllInChild(GameObject parent, string findname, bool containDeactiveobj)
{
if (null == parent)
return null;
List<GameObject> result = new List<GameObject>();
Transform[] trs = parent.GetComponentsInChildren<Transform>(containDeactiveobj);
int len = trs.Length;
for (int i = 0; i < len; ++i)
{
GameObject Tar = trs[i].gameObject;
if (findname == Tar.name)
{
result.Add(Tar);
}
}
return result.ToArray();
}
//根据Navmesh获取坐标信息
public static Vector3 GetRandomPos(Vector3 vOriginePos, float range)
{
Vector3 tPos = new Vector3(vOriginePos.x + (UnityEngine.Random.Range(-1.0f, 1.0f) * range), vOriginePos.y, vOriginePos.z + (UnityEngine.Random.Range(-1.0f, 1.0f) * range));
NavMeshPath path = new NavMeshPath();
NavMesh.CalculatePath(vOriginePos, tPos, -1, path);
if (path.corners.Length > 0)
{
tPos = path.corners[path.corners.Length - 1];
return tPos;
}else
{
NavMeshHit hit;
if (NavMesh.Raycast(vOriginePos, tPos, out hit, -1))
{
if (NavMesh.CalculatePath(vOriginePos, hit.position, -1, path))
{
tPos = path.corners[path.corners.Length - 1];
return tPos;
}
}
NavMeshHit Nvhit;
if (NavMesh.FindClosestEdge(vOriginePos, out Nvhit, -1))
{
tPos = Nvhit.position;
return tPos;
}
else
{
if (NavMesh.SamplePosition(vOriginePos, out Nvhit, range, -1))
{
tPos = Nvhit.position;
return tPos;
}
}
}
return vOriginePos;
}
//修正正朝向
private static Vector3 vForwad;
public static void FixForward(GameObject obj)
{
if (null != obj)
{
vForwad = obj.transform.eulerAngles;
vForwad.x = 0;
obj.transform.eulerAngles = vForwad;
}
}
//点投影到平面
public static Vector3 ProjectPointOnPlane(Vector3 planeNormal, Vector3 planePoint, Vector3 point)
{
float distance = Vector3.Dot(planeNormal, (point - planePoint));
distance = -distance;
Vector3 translationVector = planeNormal * distance;
return point + translationVector;
}
//模型渲染器控制
public static void SetMeshRenderVisible(GameObject parent, bool visible)
{
MeshRenderer[] rrs = parent.GetComponentsInChildren<MeshRenderer>(true);
for (int i = 0; i < rrs.Length; i++)
{
rrs[i].enabled = visible;
}
SkinnedMeshRenderer[] srs = parent.GetComponentsInChildren<SkinnedMeshRenderer>(true);
for (int i = 0; i < srs.Length; i++)
{
srs[i].enabled = visible;
}
}
//设置物理碰撞器状态
public static void SetColliderVisible(GameObject parent, bool visible)
{
Collider[] rrs = parent.GetComponentsInChildren<Collider>(true);
for (int i = 0; i < rrs.Length; i++)
{
rrs[i].enabled = visible;
}
}
//TODO
public static IEnumerator CorsValue(float time,float starValue,float endValue)
{
float start = Time.realtimeSinceStartup;
while (Time.realtimeSinceStartup < start + time)
{
yield return null;
}
}
//等待秒数
public static IEnumerator WaitForRealSeconds(float time,Action action)
{
float start = Time.realtimeSinceStartup;
while (Time.realtimeSinceStartup < start + time)
{
yield return null;
}
action?.Invoke();
}
//等待秒数
public static Coroutine WaitForSeconds(float time,Action action)
{
return MonoBehaviourHelper.StartCoroutine(WaitForRealSeconds(time,action));
}
//通过名字在父物体中查找object
public static GameObject FindInParent(GameObject startobj, string findname, bool containDeactiveobj)
{
if (null == startobj)
{
return null;
}
Transform[] trs = startobj.GetComponentsInParent<Transform>(containDeactiveobj);
int len = trs.Length;
for (int i = 0; i < len; ++i)
{
GameObject Tar = trs[i].gameObject;
if (findname == Tar.name)
{
return Tar;
}
}
return null;
}
public static T FindInScene<T>(string value) where T : Component
{
GameObject obj = FindInScene(value);
return obj?.GetComponent<T>();
}
public static GameObject FindInScene(string path)
{
if (string.IsNullOrEmpty(path))
{
return null;
}
var strPath = path.Split('/');
var objName = strPath[strPath.Length - 1];//需要查找的物体名称
//获取场景中的所有物体
var _allResourceObj = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];
var allResourceObj = _allResourceObj.ToList();
var allObj = allResourceObj.FindAll(x => x.scene.isLoaded);
if (strPath.Length==1)
{
var nameReObJ= allObj.Find(x=>x.name==objName);
return nameReObJ;
}
else
{
//查找场景中物体名称和需要查找的物体名称一样的物体
var nameReObJ= allObj.FindAll(x=>x.name==objName);
//遍历物体名称重复的物体,查找根目录
for (int i = 0; i < nameReObJ.Count; i++)
{
var obj = nameReObJ[i];
string rootPath = obj.name;
Transform parent = obj.transform.parent;
while (parent!=null)
{
var arg = parent.gameObject.name;
rootPath = arg + "/" + rootPath;
if (rootPath == path)
{
return nameReObJ[i];
} else
{
parent = parent.transform.parent;
}
}
}
}
return null;
}
//隐藏数字
public static string HidePhoneNumber(string phone)
{
System.Text.StringBuilder builder = new System.Text.StringBuilder(phone, 0, 3, 11);
builder.Append("****");
builder.Append(phone.Substring(7));
return builder.ToString();
}
//MD5加密
public static string MD5Encrypt(string text)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);
return MD5(bytes);
}
public static string MD5(byte[] value)
{
byte[] result = System.Security.Cryptography.MD5.Create().ComputeHash(value);
System.Text.StringBuilder builder = new System.Text.StringBuilder();
for (int i = 0; i < result.Length; ++i)
{
builder.Append(result[i].ToString("x2"));
}
return builder.ToString().ToUpper();
}
public static string SHA1(byte[] value)
{
byte[] result = System.Security.Cryptography.SHA1.Create().ComputeHash(value);
var builder = new System.Text.StringBuilder();
for (int i = 0; i < result.Length; i++)
{
builder.Append(result[i].ToString("x2"));
}
return builder.ToString().ToUpper();
}
public static string EnterReplace(string stext)
{
return stext.Replace("\\n", "\n");
}
public static void BillBoard(GameObject obj)
{
if (null != Camera.main && obj)
{
Vector3 vtar = Camera.main.transform.TransformVector(Vector3.forward);
Vector3 vpoint = obj.transform.position + vtar;
obj.transform.LookAt(vpoint);
}
}
public static void BoxToTriger(GameObject gt)
{
if (null != gt)
{
if (null == gt.GetComponent<Rigidbody>())
{
gt.AddComponent<Rigidbody>().isKinematic = true;
}
BoxCollider br = gt.GetComponent<BoxCollider>();
if (null != br)
{
br.isTrigger = true;
}
}
}
public static GameObject CreateBoxTriger(string name, Transform parent, Vector3 center, Vector3 size)
{
GameObject go = new GameObject(name);
go.AddComponent<Rigidbody>().isKinematic = true;
go.transform.parent = parent;
go.transform.localPosition = Vector3.zero;
go.layer = LayerMask.NameToLayer("Ignore Raycast");
go.transform.localScale = Vector3.one;//重新归0
go.transform.localEulerAngles = Vector3.zero;//重新归0
BoxCollider col = go.AddComponent<BoxCollider>();
col.isTrigger = true;
col.center = center;
col.size = size;
return go;
}
public static bool IsNetConnect()
{
bool suc = false;
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
PingReply py = ping.Send("www.baidu.com", 1000);
if (py.Status == IPStatus.Success)
{
suc = true;
}
}catch
{
suc = false;
}
return suc;
}
public static object SuperParser(string value)
{
if (string.IsNullOrEmpty(value)) { return value; }
if (value[0] == '<' && value[value.Length - 1] == '>')
{
string str = value.Substring(1, value.Length - 2);
if (str.Equals("true"))
{
return true;
}
else if (str.Equals("false"))
{
return false;
}
else if (str.EndsWith("I"))
{
return int.Parse(str.Substring(0, str.Length - 1));
}
else if (str.EndsWith("L"))
{
return long.Parse(str.Substring(0, str.Length - 1));
}
else if (str.EndsWith("F"))
{
return float.Parse(str.Substring(0, str.Length - 1));
}
else if (str.EndsWith("D"))
{
return double.Parse(str.Substring(0, str.Length - 1));
}
else if (str.StartsWith("0x"))
{
return Convert.ToInt32(str.Substring(2), 16);
}else if (str.StartsWith("0b"))
{
return Convert.ToInt32(str.Substring(2), 2);
}
else
{
return str.Substring(0, str.Length - 1);
}
}
else if (value[0] == '[' && value[value.Length - 1] == ']')
{
List<object> list = new List<object>();
string str = value.Substring(1, value.Length - 2);
string[] arr = str.Split('|');
for (int i = 0; i < arr.Length; i++)
{
object obj = SuperParser(arr[i]);
list.Add(obj);
}
return list;
}
else
{
return value.Replace("\\n", "\n");
}
}
/// <summary>
/// 反射泛型属性
/// </summary>
/// <param name="target">目标对象</param>
/// <param name="type">目标对象类型</param>
/// <param name="name">属性名</param>
/// <returns></returns>
public static object ReflectionGenericProperty(object target, Type type, string name)
{
PropertyInfo pInfo = null;
while (pInfo == null && type != null)
{
pInfo = type.GetProperty(name);
type = type.BaseType;
}
return pInfo?.GetValue(target);
}
/// <summary>
/// 反射获取对象 例: object value = SuperReflection("Game.Instance.strValue");
/// </summary>
public static object SuperReflection(object target, string path)
{
Queue<string> queue = new Queue<string>(path.Split('.'));
Type type;
if (target == null)
{
type = ParserType(queue.Dequeue());
}
else
{
type = target.GetType();
}string attName = queue.Dequeue();
object value = null;
if (value == null)
{
value = ReflectionGenericProperty(target, type, attName);
}
if (value == null)
{
FieldInfo fInfo = type.GetField(attName);
value = fInfo?.GetValue(target);
}
if (value == null)
{
MethodInfo mInfo = type.GetMethod(attName);
value = mInfo?.Invoke(target, new object[] { });
}
if (value == null)
{
return null;
}else if (queue.Count == 0)
{
return value;
}
else
{
return SuperReflection(value, string.Join(".", queue));
}
}
else if (queue.Count == 0)
{
return value;
}
else
{
return SuperReflection(value, string.Join(".", queue));
}
}
else if (queue.Count == 0)
{
return value;
}
else
{
return SuperReflection(value, string.Join(".", queue));
}
}else if (value is GameObject)
{
(value as GameObject).SetActive(active);
}
else if (value is IEnumerable)
{
foreach (object obj in (value as IEnumerable))
{
SuperActiveOrNot(active, obj);
}
}
}
public static void SuperActiveInner(object value, object indeicesObj)
{
if (value is string)
{
SuperActiveInner(FindInScene(value as string), indeicesObj);
}
else if (value is Component)
{
SuperActiveInner((value as Component).gameObject, indeicesObj);
} else if (value is GameObject)
{
GameObject obj = value as GameObject;
List<int> list = new List<int>();
if (indeicesObj is string)
{
int index = int.Parse(indeicesObj.ToString());
list.Add(index);
}else if (indeicesObj is IEnumerable)
{
int index = int.Parse(indeicesObj.ToString());
list.Add(index);
}
else
{
int index = int.Parse(indeicesObj.ToString());
list.Add(index);
}
obj.ActiveInner(list.ToArray());
}
}
public static void SuperActiveInnerHex(object value, object hexObj)
{
if (value is string)
{
SuperActiveInnerHex(FindInScene(value as string), hexObj);
}
else if (value is Component)
{
SuperActiveInnerHex((value as Component).gameObject, hexObj);
}else if (value is GameObject)
{
int hex = int.Parse(hexObj.ToString());
(value as GameObject).ActiveInnerHex(hex);
}
}
/// <summary>按位转化</summary>
public static int GetHexInt(params int[] args)
{
int result = 0;
foreach (int i in args)
{
result |= (1 << i);
}
return result;
}
public static List<T> SelectHexInt<T>(int value, params T[] args)
{
List<T> list = new List<T>();
for (int i = 0; i < args.Length; i++)
{
int iHex = 1 << i;
if ((value & iHex) == iHex)
{
list.Add(args[i]);
}
}
return list;
}
public static bool ParserVector3(string value, out Vector3 vec)
{
if (string.IsNullOrEmpty(value))
{
vec = Vector3.zero;
return false;
}
if (value.Contains("|"))
{
string[] arr = value.Split('|');
float.TryParse(arr[0], out vec.x);
float.TryParse(arr[1], out vec.y);
float.TryParse(arr[2], out vec.z);
}
else
{
vec = Vector3.one * float.Parse(value);
}
return true;
}
public static bool ParserQuration(string value, out Quaternion qua)
{
qua = Quaternion.identity;
if (ParserVector3(value, out Vector3 vec))
{
qua = Quaternion.Euler(vec);
return true;
}
else
{
return false;
}
}
public static void SyncComponet(GameObject to, GameObject from, params string[] types)
{
List<Type> list = new List<Type>();
foreach (string str in types)
{
Type type = ParserType(str);
if (type != null)
{
list.Add(type);
}
}
SyncComponet(to, from, list.ToArray());
}
public static void SyncComponet(GameObject to, GameObject from, params Type[] types)
{
for (int i = 0; i < types.Length; i++)
{
Type type = types[i];
Component toCtr = to.GetComponent(type);
Component fromCtr = from?.GetComponent(type);
if (fromCtr == null || (fromCtr is Behaviour) && !(fromCtr as Behaviour).enabled)
{
if (toCtr != null)
{
GameObject.Destroy(toCtr);
}
continue;
}
if (toCtr == null)
{
toCtr = to.AddComponent(type);
}
FieldInfo[] fInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fInfo in fInfos)
{
if (fInfo.IsPrivate && fInfo.GetCustomAttribute<SerializeField>() == null)
{
continue;
}
object value = fInfo.GetValue(fromCtr);
fInfo.SetValue(toCtr, value);
}
}
}
private static SystemLanguage mCurrentLanguage = Application.systemLanguage;
public static SystemLanguage GetCurrentLanguage() => mCurrentLanguage;
public static void SetCurrentLanguage(SystemLanguage value) => mCurrentLanguage = value;
[Obsolete] public static string GetLocalizedString(int id) => Localize(id.ToString());
[Obsolete] public static string Localize(int id, params object[] args) => Localize(id.ToString(), args);
public static string Localize(string id, params object[] args) => string.Format(Localize(id), args);
public static Color ParserColor(object value)
{
Color color = default(Color);
if (value is Color)
{
color = (Color)value;
}
else if (value is string)
{
ColorUtility.TryParseHtmlString(value as string, out color);
}
return color;
}
public static List<Component> FindComponents(GameObject target, bool includeChildren, params string[] names)
{
List<Component> list = new List<Component>();
for (int i = 0; i < names.Length; i++)
{
string name = names[i];
Type type = ParserType(name);
if (type != null)
{
if (includeChildren)
{
Component[] arr = target.GetComponentsInChildren(type);
list.AddRange(arr);
}
else
{
Component[] arr = target.GetComponents(type);
list.AddRange(arr);
}
}
}
return list;
}
public static void SimulateClick(GameObject target)
{
if (target != null && target.activeSelf)
{
BaseEventData data = new PointerEventData(EventSystem.current);
ExecuteEvents.Execute(target, data, ExecuteEvents.pointerClickHandler);
}
}
public static void Quit()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
public static string GetPkgName()
{
if (Application.isMobilePlatform)
{
return Application.identifier;
}
else
{
return string.Format("com.{0}.{1}", Application.companyName, Application.productName).ToLower();
}
}
private static DateTime ServerStartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
public static long ToServerTime(DateTime time)
{
return (long)(time - ServerStartTime).TotalMilliseconds;
}
public static string UrlJoin(string url, Dictionary<string, string> args)
{
bool isFirst = !url.Contains("?");
if (args != null)
{
foreach (var kv in args)
{
url += string.Format("{0}{1}={2}", isFirst ? "?" : "&", kv.Key, kv.Value);
isFirst = false;
}
}
return url;
}
public static Dictionary<string, string> UrlSplit(string url)
{
Dictionary<string, string> map = new Dictionary<string, string>();
string[] arr = url.Split(new char[] { '?', '&' });
for (int i = 1; i < arr.Length; i++)
{
string kvStr = arr[i];
int index = kvStr.IndexOf('=');
string key = kvStr.Substring(0, index);
string value = kvStr.Substring(index + 1);
map[key] = value;
}
return map;
}
public static void CalculateCorners(RectTransform tran, out Vector2 min, out Vector2 max)
{
Vector2 center = tran.anchoredPosition;
Vector2 half = tran.sizeDelta * 0.5f;
min = center - half;
max = center + half;
if (Application.isEditor)
{
Vector3 v0 = tran.parent.TransformPoint(min);
Vector3 v1 = tran.parent.TransformPoint(new Vector2(min.x, max.y));
Vector3 v2 = tran.parent.TransformPoint(max);
Vector3 v3 = tran.parent.TransformPoint(new Vector2(max.x, min.y));
Debug.DrawLine(v0, v1, Color.red);
Debug.DrawLine(v0, v3, Color.red);
Debug.DrawLine(v2, v1, Color.red);
Debug.DrawLine(v2, v3, Color.red);
}
}
public static int ClosestOffset(RectTransform from, RectTransform to, out Vector2 offset)
{
CalculateCorners(from, out Vector2 fMin, out Vector2 fMax);
CalculateCorners(to, out Vector2 tMin, out Vector2 tMax);
float x1 = tMax.x - fMin.x;
float x2 = tMin.x - fMax.x;
float y1 = tMax.y - fMin.y;
float y2 = tMin.y - fMax.y;
float x = (Math.Abs(x1) < Math.Abs(x2)) ? x1 : x2;
float y = (Math.Abs(y1) < Math.Abs(y2) ? y1 : y2);
offset = Vector2.zero;
if (x1 > 0 && x2 < 0 && y1 > 0 && y2 < 0)
{
if (Math.Abs(x) < Math.Abs(y))
{
offset.x = x;
}
else
{
offset.y = y;
}
return -1;
}
else
{
if (x1 < 0 || x2 > 0)
{
offset.x = x;
}
if (y1 < 0 || y2 > 0)
{
offset.y = y;
}
return offset.magnitude == 0 ? 0 : 1;
}
}
/// <summary>
/// 设置位置
/// </summary>
/// <param name="tran"></param>
/// <param name="positionValue"></param>
/// <param name="scaleValue"></param>
/// <param name="rotateValue"></param>
public static Coroutine SetLocalTransform(Transform tran, string positionValue, string scaleValue, string rotateValue, float duration)
{
Ywa_Object behaviour = tran.gameObject.AddComponent<Ywa_Object>();
return behaviour.StartCoroutine(DoSetLocalTransform(behaviour, tran, positionValue, scaleValue, rotateValue, duration));
}
private static IEnumerator DoSetLocalTransform(Ywa_Object ctl, Transform tran, string positionValue, string scaleValue, string rotateValue, float duration)
{
Vector3 positionStart = tran.localPosition;
Vector3 scaleStart = tran.localScale;
Quaternion rotateStart = tran.localRotation;
if (!ParserVector3(positionValue, out Vector3 positionEnd))
{
positionEnd = tran.localPosition;
}
if (!ParserVector3(scaleValue, out Vector3 scaleEnd))
{
scaleEnd = tran.localScale;
}
Quaternion rotateEnd;
if (ParserVector3(rotateValue, out Vector3 euler))
{
rotateEnd = Quaternion.Euler(euler);
}
else
{
rotateEnd = tran.localRotation;
}
float time = 0;
float progress;
while (time < duration)
{
progress = time / duration;
tran.localPosition = Vector3.Lerp(positionStart, positionEnd, progress);
tran.localScale = Vector3.Lerp(scaleStart, scaleEnd, progress);
tran.localRotation = Quaternion.Lerp(rotateStart, rotateEnd, progress);
yield return new WaitForEndOfFrame();
time += Time.deltaTime;
}
tran.localPosition = positionEnd;
tran.localScale = scaleEnd;
tran.localRotation = rotateEnd;
GameObject.Destroy(ctl);
}
}