射线检测,实现范围射线检测,可以实时调整射线现实方向,也有相应方法调用,获取使用

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


}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值