Unity在进行射线检测时忽略掉指定的碰撞器

发布时间 2023-08-22 16:21:19作者: Jason_c
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    public Transform startPoint; // 起始点
    public Transform endPoint; // 结束点

    public List<Collider> ignoreList;

    private void Start()
    {
        if (Linecast(startPoint.position, endPoint.position, ignoreList, -5, out RaycastHit hit))
        {
            Debug.LogError(hit.collider.name);
        }
        else
        {
            Debug.LogError("no find");
        }
    }

    /// <summary>
    /// 射线检测可以忽略指定的Collider,
    /// </summary>
    bool Linecast(Vector3 start, Vector3 end, List<Collider> ignored, int layerMask, out RaycastHit raycastHit)
    {
        Vector3 direction = end - start;
        RaycastHit[] hits = Physics.RaycastAll(start, direction.normalized, direction.magnitude, layerMask);

        //返回的数组是无序的,按距离start的远近,排下序
        System.Array.Sort(hits, (left, right) => { return left.distance.CompareTo(right.distance); });

        foreach (RaycastHit hit in hits)
        {
            //检测到的点不是起始点
            if (hit.point != start && hit.point != end)
            {
                //检测到的物体没有在忽略名单里
                if (!Contains(ignored, hit))
                {
                    raycastHit = hit;
                    return true;
                }
            }
        }
        raycastHit = default;
        return false;
    }

    /// <summary>
    /// 等于或在Collider的内部
    /// </summary>
    public bool Contains(List<Collider> colliders, RaycastHit hit)
    {
        foreach (var collider in colliders)
        {
            if (collider == hit.collider || collider.bounds.Contains(hit.point))
            {
                return true;
            }
        }
        return false;
    }

}