CultivateImmortal/Assets/Scripts/Framework/Util/MathUtil.cs
2024-11-14 18:15:51 +08:00

256 lines
9.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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