/*
*Copyright(C) 2020 by GYYX All rights reserved.
*Unity版本:2018.4.36f1
*作者:Chief
*创建日期: 2022-01-04
*模块说明:
*版本: 1.2
*/
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
namespace Oroxylum
{
///
/// 通用工具;
///
public static class Utils
{
#region 组件相关
public static GameObject CreateGameObjectAtPath(string path)
{
if (string.IsNullOrEmpty(path))
return null;
var obj = GameObject.Find(path);
if (obj == null)
{
//在最近父节点进行创建;
var index = path.LastIndexOf('/');
if (index == -1)
return new GameObject(path);
var parentPath = path.Substring(0, index);
var selftPath = path.Substring(index + 1);
obj = new GameObject(selftPath);
var parent = CreateGameObjectAtPath(parentPath);
if (parent != null)
obj.transform.parent = parent.transform;
obj.NormalizeGameObject();
}
return obj;
}
public static Transform CreateTransformAtParent(string name, Transform parentTrans)
{
var go = new GameObject(name);
go.SetParent(parentTrans);
go.NormalizeGameObject();
return go.transform;
}
public static Transform CreateChild(this Transform parentTrans, string name)
{
var go = new GameObject(name);
go.SetParent(parentTrans);
go.NormalizeGameObject();
return go.transform;
}
public static void NormalizeGameObject(this GameObject target)
{
target.transform.localPosition = Vector3.zero;
target.transform.localRotation = Quaternion.identity;
target.transform.localScale = Vector3.one;
}
[System.Obsolete("使用 SetActiveSafe 替换。")]
public static void SetActive2(this GameObject obj, bool active) { obj.SetActiveSafe(active); }
public static void SetActiveSafe(this GameObject obj, bool active)
{
if (obj == null)
return;
if (obj.activeSelf == active)
return;
obj.SetActive(active);
}
[System.Obsolete("使用 SetActiveSafe 替换。")]
public static void SetActive2(this Component compT, bool active) { compT.SetActiveSafe(active); }
public static void SetActiveSafe(this Component compT, bool active)
{
if (compT == null)
return;
compT.gameObject.SetActiveSafe(active);
}
public static void Destory(this UnityEngine.Object obj)
{
if (obj == null)
return;
//特殊:于Transform的判定;
if (obj is Transform)
(obj as Transform).gameObject.Destory();
#if UNITY_EDITOR
if (!Application.isPlaying)
UnityEngine.Object.DestroyImmediate(obj);
else
#endif
UnityEngine.Object.Destroy(obj);
}
///
/// 获取层级名;
///
public static string GetHierarchyName(this Transform trans)
{
if (trans == null)
return null;
string name = trans.name;
var parent = trans.parent;
while (parent != null)
{
name = $"{parent.name}/{name}";
parent = parent.parent;
}
return name;
}
///
/// 获取根节点
///
///
public static Transform GetRootTransform(this Transform trans)
{
if (trans == null)
return null;
if (trans.parent == null)
return trans;
return trans.parent.GetRootTransform();
}
///
/// 获取,或者添加一个组件;
///
public static T GetOrAddComponent(this GameObject obj) where T : Component
{
if (obj == null)
return null;
var compt = obj.GetComponent();
if (compt == null)
compt = obj.AddComponent();
return compt;
}
///
/// 获取,或者添加一个组件;
///
public static T GetOrAddComponent(this Transform trans) where T : Component
{
if (trans == null)
return null;
return trans.gameObject.GetOrAddComponent();
}
///
/// 获取,或者添加一个组件;
///
public static T GetOrAddComponent(this Component compt) where T : Component
{
if (compt == null)
return null;
return compt.gameObject.GetOrAddComponent();
}
#endregion
#region 扩展方法
public static void AddOrReplace(this Dictionary dict, T1 key, T2 val)
{
if (dict == null)
return;
if (key == null || val == null)
return;
if (dict.ContainsKey(key))
dict[key] = val;
else
dict.Add(key, val);
}
public static void AddOrIngore(this Dictionary dict, T1 key, T2 val)
{
if (dict == null)
return;
if (key == null || val == null)
return;
if (dict.ContainsKey(key))
return;
else
dict.Add(key, val);
}
public static T2 GetValue(this Dictionary dict, T1 key)
{
if (dict == null)
return default(T2);
T2 ret;
dict.TryGetValue(key, out ret);
return ret;
}
public static long Int2ToLong(Vector2Int v)
{
int q = v.x, r = v.y;
long rt = (long)q << 32;
rt = rt | (r & 0xffffffff);
return rt;
}
public static Vector2Int LongToInt2(long id)
{
int x = (int)(id >> 32);
int y = (int)id;
return new Vector2Int(x, y);
}
///
/// 通过线性采样获得的颜色值;
///
public static Color GetBilinearPixel(NativeArray pixelData, float u, float v, int width, int height)
{
u *= width;
v *= height;
width = Mathf.Max(width, 2);
height = Mathf.Max(height, 2);
int x = Mathf.Clamp(Mathf.FloorToInt(u), 0, width - 2);
int y = Mathf.Clamp(Mathf.FloorToInt(v), 0, height - 2);
float s = u - x;
float t = v - y;
Color c1 = pixelData[x + (y * width)];
Color c2 = pixelData[x + 1 + (y * width)];
Color c3 = pixelData[x + ((y + 1) * width)];
Color c4 = pixelData[x + 1 + ((y + 1) * width)];
Color a = Color.Lerp(c1, c2, s);
Color b = Color.Lerp(c3, c4, s);
return Color.Lerp(a, b, t);
}
#endregion
#region 数学计算
///
/// 计算直线与平面的交点
///
/// 通用的部分;
///
/// ——程一峰;2020.11.09
///
/// 直线上某一点
/// 直线的方向
/// 垂直于平面的的向量
/// 平面上的任意一点
///
public static Vector3 GetIntersectWithLineAndPlane(Vector3 point, Vector3 direct, Vector3 planeNormal, Vector3 planePoint)
{
float d = Vector3.Dot(planePoint - point, planeNormal) / Vector3.Dot(direct.normalized, planeNormal);
//直线与平面的交点
Vector3 hitPoint = (d * direct.normalized) + point;
return hitPoint;
}
///
/// 点到直线的距离;
///
/// 目标点
/// 直线上一点
/// 直线上另一点
///
public static float GetDistancePointToLine(Vector3 point, Vector3 linePoint1, Vector3 linePoint2)
{
Vector3 vec1 = point - linePoint1;
Vector3 vec2 = linePoint2 - linePoint1;
Vector3 vecProj = Vector3.Project(vec1, vec2);
float dis = Mathf.Sqrt(Mathf.Pow(Vector3.Magnitude(vec1), 2) - Mathf.Pow(Vector3.Magnitude(vecProj), 2));
return dis;
}
///
///
/// 计算射线与平面的交点
///
/// 通用的部分;
///
/// ——程一峰;2020.11.17
///
/// 射线
/// 垂直于平面的的向量
/// 平面上的任意一点
///
public static Vector3 GetIntersectWithLineAndPlane(Ray ray, Vector3 planeNormal, Vector3 planePoint) { return GetIntersectWithLineAndPlane(ray.origin, ray.direction, planeNormal, planePoint); }
///
///
/// 计算射线与水平平面的交点
///
/// 通用的部分;
///
/// ——程一峰;2020.11.17
///
/// 射线
/// 高度
///
public static Vector3 GetIntersectWithLineAndPlane(Ray ray, float height)
{
var point = GetIntersectWithLineAndPlane(ray.origin, ray.direction, Vector3.up, new Vector3(0, height, 0));
point.y = height;
return point;
}
///
/// 将值限制在两个Vector3之间
///
///
///
///
///
public static Vector3 Clamp(Vector3 pos, Vector3 min, Vector3 max)
{
pos.x = Mathf.Clamp(pos.x, min.x, max.x);
pos.y = Mathf.Clamp(pos.y, min.y, max.y);
pos.z = Mathf.Clamp(pos.z, min.z, max.z);
return pos;
}
public static Vector2 Clamp(this Vector2 source, Vector2 min, Vector2 max)
{
source.x = Mathf.Clamp(source.x, min.x, max.x);
source.y = Mathf.Clamp(source.y, min.y, max.y);
return source;
}
///
/// 距离的平方;
///
public static float DistanceSq(Vector3 a, Vector3 b)
{
float xSq = (a.x - b.x) * (a.x - b.x);
float ySq = (a.y - b.y) * (a.y - b.y);
float zSq = (a.z - b.z) * (a.z - b.z);
return xSq + ySq + zSq;
}
///
/// 距离的平方;
///
public static float DistanceSq(Vector2 a, Vector2 b)
{
float xSq = (a.x - b.x) * (a.x - b.x);
float ySq = (a.y - b.y) * (a.y - b.y);
return xSq + ySq;
}
///
/// 获取坐标差值之和;
/// 忽略Y轴;
/// 这个计算值一定大于等于其实际距离;
///
public static float Distance_FastByCoDiff_NoY(Vector3 v1, Vector3 v2)
{
float x = v1.x - v2.x;
if (x < 0)
x = -x;
float z = v1.z - v2.z;
if (z < 0)
z = -z;
return x + z;
}
#endregion
#region 字符串操作
///
/// 把字符串用 . 分开;
/// 然后获取最后一个字符串;
///
///
///
public static string GetLastStrAfterDot(string oldStr)
{
var arrStr = oldStr.Split('.');
return arrStr[arrStr.Length - 1];
}
#endregion
}
}