using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class MathUtil { #region 角度和弧度 /// /// 角度转弧度的方法 /// /// 角度值 /// 弧度值 public static float Deg2Rad(float deg) { return deg * Mathf.Deg2Rad; } /// /// 弧度转角度的方法 /// /// 弧度值 /// 角度值 public static float Rad2Deg(float rad) { return rad * Mathf.Rad2Deg; } #endregion #region 距离计算相关的 /// /// 获取XZ平面上 两点的距离 /// /// 点1 /// 点2 /// public static float GetObjDistanceXZ(Vector3 srcPos, Vector3 targetPos) { srcPos.y = 0; targetPos.y = 0; return Vector3.Distance(srcPos, targetPos); } /// /// 判断两点之间距离 是否小于等于目标距离 XZ平面 /// /// 点1 /// 点2 /// 距离 /// public static bool CheckObjDistanceXZ(Vector3 srcPos, Vector3 targetPos, float dis) { return GetObjDistanceXZ(srcPos, targetPos) <= dis; } /// /// 获取XY平面上 两点的距离 /// /// 点1 /// 点2 /// public static float GetObjDistanceXY(Vector3 srcPos, Vector3 targetPos) { srcPos.z = 0; targetPos.z = 0; return Vector3.Distance(srcPos, targetPos); } /// /// 判断两点之间距离 是否小于等于目标距离 XY平面 /// /// 点1 /// 点2 /// 距离 /// public static bool CheckObjDistanceXY(Vector3 srcPos, Vector3 targetPos, float dis) { return GetObjDistanceXY(srcPos, targetPos) <= dis; } #endregion #region 位置判断相关 /// /// 判断世界坐标系下的某一个点 是否在屏幕可见范围外 /// /// 世界坐标系下的一个点的位置 /// 如果在可见范围外返回true,否则返回false public static bool IsWorldPosOutScreen(Vector3 pos) { //将世界坐标转为屏幕坐标 Vector3 screenPos = Camera.main.WorldToScreenPoint(pos); //判断是否在屏幕范围内 if (screenPos.x >= 0 && screenPos.x <= Screen.width && screenPos.y >= 0 && screenPos.y <= Screen.height) return false; return true; } /// /// 判断某一个位置 是否在指定扇形范围内(注意:传入的坐标向量都必须是基于同一个坐标系下的) /// /// 扇形中心点位置 /// 自己的面朝向 /// 目标对象 /// 半径 /// 扇形的角度 /// public static bool IsInSectorRangeXZ(Vector3 pos, Vector3 forward, Vector3 targetPos, float radius, float angle) { pos.y = 0; forward.y = 0; targetPos.y = 0; //距离 + 角度 return Vector3.Distance(pos, targetPos) <= radius && Vector3.Angle(forward, targetPos - pos) <= angle / 2f; } #endregion #region 射线检测相关 /// /// 射线检测 获取一个对象 指定距离 指定层级的 /// /// 射线 /// 回调函数(会把碰到的RayCastHit信息传递出去) /// 最大距离 /// 层级筛选 public static void RayCast(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit hitInfo; if(Physics.Raycast(ray, out hitInfo, maxDistance, layerMask)) callBack.Invoke(hitInfo); } /// /// 射线检测 获取一个对象 指定距离 指定层级的 /// /// 射线 /// 回调函数(会把碰到的GameObject信息传递出去) /// 最大距离 /// 层级筛选 public static void RayCast(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask)) callBack.Invoke(hitInfo.collider.gameObject); } /// /// 射线检测 获取一个对象 指定距离 指定层级的 /// /// 射线 /// 回调函数(会把碰到的对象信息上挂在的指定脚本传递出去) /// 最大距离 /// 层级筛选 public static void RayCast(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask)) callBack.Invoke(hitInfo.collider.gameObject.GetComponent()); } /// /// 射线检测 获取到多个对象 指定距离 指定层级 /// /// 射线 /// 回调函数(会把碰到的RayCastHit信息传递出去) 每一个对象都会调用一次 /// 最大距离 /// 层级筛选 public static void RayCastAll(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit[] hitInfos = Physics.RaycastAll(ray, maxDistance, layerMask); for (int i = 0; i < hitInfos.Length; i++) callBack.Invoke(hitInfos[i]); } /// /// 射线检测 获取到多个对象 指定距离 指定层级 /// /// 射线 /// 回调函数(会把碰到的GameObject信息传递出去) 每一个对象都会调用一次 /// 最大距离 /// 层级筛选 public static void RayCastAll(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit[] hitInfos = Physics.RaycastAll(ray, maxDistance, layerMask); for (int i = 0; i < hitInfos.Length; i++) callBack.Invoke(hitInfos[i].collider.gameObject); } /// /// 射线检测 获取到多个对象 指定距离 指定层级 /// /// 射线 /// 回调函数(会把碰到的对象信息上依附的脚本传递出去) 每一个对象都会调用一次 /// 最大距离 /// 层级筛选 public static void RayCastAll(Ray ray, UnityAction callBack, float maxDistance, int layerMask) { RaycastHit[] hitInfos = Physics.RaycastAll(ray, maxDistance, layerMask); for (int i = 0; i < hitInfos.Length; i++) callBack.Invoke(hitInfos[i].collider.gameObject.GetComponent()); } #endregion #region 范围检测相关 /// /// 进行盒装范围检测 /// /// 想要获取的信息类型 可以填写 Collider GameObject 以及对象上依附的组件类型 /// 盒装中心点 /// 盒子的角度 /// 长宽高的一半 /// 层级筛选 /// 回调函数 public static void OverlapBox(Vector3 center, Quaternion rotation, Vector3 halfExtents, int layerMask, UnityAction callBack) where T : class { Type type = typeof(T); Collider[] colliders = Physics.OverlapBox(center, halfExtents, rotation, layerMask, QueryTriggerInteraction.Collide); for (int i = 0; i < colliders.Length; i++) { if (type == typeof(Collider)) callBack.Invoke(colliders[i] as T); else if (type == typeof(GameObject)) callBack.Invoke(colliders[i].gameObject as T); else callBack.Invoke(colliders[i].gameObject.GetComponent()); } } /// /// 进行球体范围检测 /// /// 想要获取的信息类型 可以填写 Collider GameObject 以及对象上依附的组件类型 /// 球体的中心点 /// 球体的半径 /// 层级筛选 /// 回调函数 public static void OverlapSphere(Vector3 center, float radius, int layerMask, UnityAction callBack) where T:class { Type type = typeof(T); Collider[] colliders = Physics.OverlapSphere(center, radius, layerMask, QueryTriggerInteraction.Collide); for (int i = 0; i < colliders.Length; i++) { if (type == typeof(Collider)) callBack.Invoke(colliders[i] as T); else if (type == typeof(GameObject)) callBack.Invoke(colliders[i].gameObject as T); else callBack.Invoke(colliders[i].gameObject.GetComponent()); } } #endregion }