using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 射线检测范围
///
namespace RayDetectionRange
{
public enum RayCenterPointsType
{
Single,//单个中心点
Multiple//多个中心点
}
/// <summary>
/// 射线传感器基础
/// </summary>
[ExecuteInEditMode]
public class RaySensorBase : MonoBehaviour
{
public RayCenterPointsType m_RayType;
/// <summary>
/// 检测半径
/// </summary>
public float m_RayRang = 2f;
/// <summary>
/// 射线横向数量
/// </summary>
[Range(0, 72)]
public int m_RayNumberX = 5;
/// <summary>
/// 射线纵向数量
/// </summary>
[Range(0, 18)]
public int m_RayNumberY = 1;
/// <summary>
/// 射线横向检测角度
/// </summary>
[Range(0.0f, 360.0f)]
public float m_RayAngleX = 10;
/// <summary>
/// 射线纵向检测角度
/// </summary>
[Range(0.0f, 180.0f)]
public float m_RayAngleY = 10;
/// <summary>
/// 射线差值角度
/// </summary>
[Range(0.0f, 2.0f)]
public float m_RayDiffAngle = 0;
/// <summary>
/// 射线中心点
/// </summary>
public Vector3 M_RayCenterPoint
{
get
{
return m_RayCenterPoint + this.transform.position;
}
}
protected Vector3 m_RayCenterPoint;
#region 设置编辑
void OnEnable()
{
}
void OnValidate()
{
CreateCollider();
}
#endregion
/// <summary>
/// 射线中心点以及方向点字典
/// </summary>
Dictionary<Vector3, List<Vector3>> M_RayCenterAndDirPointsDic
{
get
{
if (m_RayCenterAndDirPointsDic == null)
{
m_RayCenterAndDirPointsDic = new Dictionary<Vector3, List<Vector3>>();
CreateCollider();
}
return m_RayCenterAndDirPointsDic;
}
}
Dictionary<Vector3, List<Vector3>> m_RayCenterAndDirPointsDic;
public void CreateCollider()
{
if (m_RayCenterAndDirPointsDic!=null)
{
M_RayCenterAndDirPointsDic.Clear();
}
m_RayCenterPoint = Vector3.zero;
for (int y = 0; y < 2 + m_RayNumberY; y++)
{
List<Vector3> list = new List<Vector3>();
float CenterY = 0;
for (int x = 0; x < 2 + m_RayNumberX; x++)
{
int i = 4 + y * (2 + m_RayNumberX) + x;
float ay = Mathf.Lerp(-m_RayAngleX / 2f, m_RayAngleX / 2f, (float)x / (float)(m_RayNumberX + 1));
float ax = Mathf.Lerp(-m_RayAngleY, m_RayAngleY, (float)y / (float)(m_RayNumberY + 1));
Vector3 p = Quaternion.Euler(ax, ay, 0f) * Vector3.forward * m_RayRang;
if (!list.Contains(p))
{
list.Add(p);
}
CenterY = p.y;
}
AddRayCenterAndDirPointsDic(new Vector3(0, CenterY, 0),list);
}
}
private void AddRayCenterAndDirPointsDic(Vector3 key,List<Vector3> value)
{
if (!M_RayCenterAndDirPointsDic.ContainsKey(key))
{
M_RayCenterAndDirPointsDic.Add(key, value);
}
}
void OnDrawGizmosSelected()
{
switch (m_RayType)
{
case RayCenterPointsType.Single:
SingleDrawGizmos();
break;
case RayCenterPointsType.Multiple:
MultipleDrawGizmos();
break;
}
}
#region 划线
/// <summary>
/// 单个中心点划线
/// </summary>
protected virtual void SingleDrawGizmos()
{
Gizmos.DrawSphere(transform.TransformPoint(m_RayCenterPoint), 0.1f);
foreach (var posList in M_RayCenterAndDirPointsDic.Values)
{
foreach (var pos in posList)
{
Gizmos.DrawSphere(transform.TransformPoint(pos), 0.1f);
Gizmos.DrawLine(transform.TransformPoint(m_RayCenterPoint), transform.TransformPoint(pos));
}
}
}
/// <summary>
/// 多个中心点划线
/// </summary>
protected virtual void MultipleDrawGizmos()
{
foreach (var CenterPos in M_RayCenterAndDirPointsDic.Keys)
{
Gizmos.DrawSphere(transform.TransformPoint(CenterPos), 0.1f);
foreach (var pos in M_RayCenterAndDirPointsDic[CenterPos])
{
Gizmos.DrawSphere(transform.TransformPoint(pos), 0.1f);
Gizmos.DrawLine(transform.TransformPoint(CenterPos), transform.TransformPoint(pos));
}
}
}
#endregion
#region 获取射线
/// <summary>
/// 获取射线列表
/// </summary>
public virtual List<Ray> GetRayList
{
get
{
switch (m_RayType)
{
case RayCenterPointsType.Single:
return GetRaySingleList;
case RayCenterPointsType.Multiple:
return GetRayMultipleList;
}
return null;
}
}
/// <summary>
/// 获取单个中心点射线列表
/// </summary>
protected virtual List<Ray> GetRaySingleList
{
get
{
List<Ray> list = new List<Ray>();
foreach (var posList in M_RayCenterAndDirPointsDic.Values)
{
foreach (var pos in posList)
{
Vector3 dir = (transform.TransformPoint(pos) - transform.TransformPoint(m_RayCenterPoint)).normalized;
Ray ray = new Ray(transform.TransformPoint(m_RayCenterPoint),dir);
list.Add(ray);
}
}
return list;
}
}
/// <summary>
/// 获取多个中心点射线列表
/// </summary>
protected virtual List<Ray> GetRayMultipleList
{
get
{
List<Ray> list = new List<Ray>();
foreach (var CenterPos in M_RayCenterAndDirPointsDic.Keys)
{
foreach (var pos in M_RayCenterAndDirPointsDic[CenterPos])
{
Vector3 dir = (transform.TransformPoint(pos) - transform.TransformPoint(CenterPos)).normalized;
Ray ray = new Ray(transform.TransformPoint(CenterPos), dir);
list.Add(ray);
}
}
return list;
}
}
#endregion
#region 获取中心点以及射线方向
/// <summary>
/// 获取中心点以及方向
/// </summary>
public virtual Dictionary<Vector3, List<Vector3>> GetRayCenterAndDirDic
{
get
{
switch (m_RayType)
{
case RayCenterPointsType.Single:
return GetRaySingleCenterAndDirDic;
case RayCenterPointsType.Multiple:
return GetRayMultipleCenterAndDirDic;
}
return null;
}
}
/// <summary>
/// 获取单个中心点以及方向
/// </summary>
protected virtual Dictionary<Vector3, List<Vector3>> GetRaySingleCenterAndDirDic
{
get
{
Dictionary<Vector3, List<Vector3>> dic = new Dictionary<Vector3, List<Vector3>>();
List<Vector3> list = new List<Vector3>();
foreach (var posList in M_RayCenterAndDirPointsDic.Values)
{
foreach (var pos in posList)
{
Vector3 dir = (transform.TransformPoint(pos) - transform.TransformPoint(m_RayCenterPoint)).normalized;
list.Add(dir);
}
}
dic.Add(transform.TransformPoint(m_RayCenterPoint), list);
return dic;
}
}
/// <summary>
/// 获取多个中心点以及方向
/// </summary>
protected virtual Dictionary<Vector3, List<Vector3>> GetRayMultipleCenterAndDirDic
{
get
{
Dictionary<Vector3, List<Vector3>> dic = new Dictionary<Vector3, List<Vector3>>();
foreach (var CenterPos in M_RayCenterAndDirPointsDic.Keys)
{
List<Vector3> list = new List<Vector3>();
foreach (var pos in M_RayCenterAndDirPointsDic[CenterPos])
{
Vector3 dir = (transform.TransformPoint(pos) - transform.TransformPoint(CenterPos)).normalized;
list.Add(dir);
}
dic.Add(transform.TransformPoint(CenterPos), list);
}
return dic;
}
}
#endregion
#region 获取对象
/// <summary>
/// 获取检测对象
/// </summary>
public virtual List<GameObject> GetDetected()
{
List<GameObject> objList = new List<GameObject>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject==null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy==false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject))
{
continue;
}
objList.Add(hit.transform.gameObject);
}
}
return objList;
}
/// <summary>
/// 通过组件获取检测对象
/// </summary>
public virtual List<T> GetDetectedByComponent<T>()
{
List<T> objList = new List<T>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.GetComponent<T>()!=null)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject.GetComponent<T>()))
{
continue;
}
objList.Add(hit.transform.gameObject.GetComponent<T>());
}
}
}
return objList;
}
/// <summary>
/// 通过名称获取检测对象
/// </summary>
public List<GameObject> GetDetectedByName(string name)
{
List<GameObject> objList = new List<GameObject>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.name == name)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject))
{
continue;
}
objList.Add(hit.transform.gameObject);
}
}
}
return objList;
}
/// <summary>
/// 通过组件和名称获取检测对象
/// </summary>
public List<T> GetDetectedByNameAndComponent<T>(string name) where T : Component
{
List<T> objList = new List<T>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.GetComponent<T>() != null&& hit.transform.gameObject.name==name)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject.GetComponent<T>()))
{
continue;
}
objList.Add(hit.transform.gameObject.GetComponent<T>());
}
}
}
return objList;
}
/// <summary>
/// 通过标签获取检测对象
/// </summary>
public List<GameObject> GetDetectedByTag(string tag)
{
List<GameObject> objList = new List<GameObject>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.tag == tag)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject))
{
continue;
}
objList.Add(hit.transform.gameObject);
}
}
}
return objList;
}
/// <summary>
/// 通过组件和标签获取检测对象
/// </summary>
public List<T> GetDetectedByTagAndComponent<T>(string tag) where T : Component
{
List<T> objList = new List<T>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.GetComponent<T>() != null && hit.transform.gameObject.tag == tag)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject.GetComponent<T>()))
{
continue;
}
objList.Add(hit.transform.gameObject.GetComponent<T>());
}
}
}
return objList;
}
/// <summary>
/// 通过名称和标签获取检测对象
/// </summary>
public List<GameObject> GetDetectedByNameAndTag(string name, string tag)
{
List<GameObject> objList = new List<GameObject>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.tag == tag&& hit.transform.gameObject.name == name)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject))
{
continue;
}
objList.Add(hit.transform.gameObject);
}
}
}
return objList;
}
/// <summary>
/// 通过组件、名称和标签获取检测对象
/// </summary>
public List<T> GetDetectedByNameAndTagAndComponent<T>(string name, string tag) where T : Component
{
List<T> objList = new List<T>();
List<Ray> raysList = GetRayList;
foreach (var ray in raysList)
{
RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, m_RayRang);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.GetComponent<T>() != null && hit.transform.gameObject.name == name && hit.transform.gameObject.tag == tag)
{
if (hit.transform.gameObject == null)
{
continue;
}
if (hit.transform.gameObject.activeInHierarchy == false)
{
continue;
}
if (objList.Contains(hit.transform.gameObject.GetComponent<T>()))
{
continue;
}
objList.Add(hit.transform.gameObject.GetComponent<T>());
}
}
}
return objList;
}
#endregion
}
}