You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中聚光灯绕X轴旋转时,如何精准检测被照射的玩家?

Unity聚光灯照射玩家的高精度检测方案

方案一:圆锥范围+角度判断+遮挡校验

先通过范围检测快速筛选候选目标,再用角度判断是否处于聚光灯照射锥体内,最后补充射线检测排除障碍物遮挡,兼顾精度与性能。

using UnityEngine;

public class SpotlightDetection : MonoBehaviour
{
    public Spotlight spotlight;
    public LayerMask playerLayer;
    private float halfConeAngle;
    private float maxRange;

    void Start()
    {
        halfConeAngle = spotlight.spotAngle / 2f;
        maxRange = spotlight.range;
    }

    void Update()
    {
        // 检测聚光灯范围内的所有玩家层物体
        Collider[] hitColliders = Physics.OverlapSphere(transform.position, maxRange, playerLayer);
        
        foreach (Collider collider in hitColliders)
        {
            // 计算聚光灯指向玩家的方向向量
            Vector3 directionToPlayer = collider.transform.position - transform.position;
            directionToPlayer.Normalize();
            
            // 判断玩家是否在聚光灯的圆锥范围内
            float angle = Vector3.Angle(transform.forward, directionToPlayer);
            if (angle <= halfConeAngle)
            {
                // 校验是否有障碍物遮挡
                if (Physics.Linecast(transform.position, collider.transform.position, out RaycastHit hit, ~playerLayer))
                {
                    if (hit.collider == collider)
                    {
                        Debug.Log("玩家被聚光灯照射到");
                        // 此处添加你的触发逻辑,比如警报、高亮等
                    }
                }
            }
        }
    }
}

方案二:多射线覆盖圆锥区域

通过生成多条射线覆盖聚光灯的照射圆锥,解决单射线检测精度不足的问题,射线数量可根据需求调整。

using UnityEngine;

public class SpotlightMultiRayDetection : MonoBehaviour
{
    public Spotlight spotlight;
    public LayerMask playerLayer;
    public int rayCount = 20; // 射线数量,越多精度越高
    private float halfConeAngle;
    private float maxRange;

    void Start()
    {
        halfConeAngle = spotlight.spotAngle / 2f;
        maxRange = spotlight.range;
    }

    void Update()
    {
        bool playerDetected = false;
        
        // 绕X轴生成覆盖圆锥的射线(匹配聚光灯旋转轴)
        for (int i = 0; i < rayCount; i++)
        {
            float currentAngle = Mathf.Lerp(-halfConeAngle, halfConeAngle, (float)i / (rayCount - 1));
            Quaternion rayRotation = Quaternion.Euler(currentAngle, 0, 0);
            Vector3 rayDirection = rayRotation * transform.forward;
            
            if (Physics.Raycast(transform.position, rayDirection, out RaycastHit hit, maxRange, playerLayer))
            {
                playerDetected = true;
                break;
            }
        }
        
        if (playerDetected)
        {
            Debug.Log("玩家被聚光灯照射到");
            // 执行你的逻辑
        }
    }
}

方案三:触发器+角度校验

用触发器模拟聚光灯的照射范围,玩家进入触发器后再判断是否处于有效照射角度,减少不必要的计算。

  1. 创建聚光灯的子物体,添加CapsuleCollider并调整尺寸匹配聚光灯圆锥范围,勾选Is Trigger;
  2. 挂载以下脚本:
using UnityEngine;

public class SpotlightTriggerDetection : MonoBehaviour
{
    public Spotlight spotlight;
    public LayerMask playerLayer;
    private float halfConeAngle;

    void Start()
    {
        halfConeAngle = spotlight.spotAngle / 2f;
    }

    void OnTriggerStay(Collider other)
    {
        if (((1 << other.gameObject.layer) & playerLayer) != 0)
        {
            Vector3 directionToPlayer = other.transform.position - spotlight.transform.position;
            directionToPlayer.Normalize();
            float angle = Vector3.Angle(spotlight.transform.forward, directionToPlayer);
            
            if (angle <= halfConeAngle)
            {
                if (Physics.Linecast(spotlight.transform.position, other.transform.position, out RaycastHit hit, ~playerLayer))
                {
                    if (hit.collider == other)
                    {
                        Debug.Log("玩家被聚光灯照射到");
                        // 执行你的逻辑
                    }
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Dhanesh0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:20:27