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
}