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("玩家被聚光灯照射到"); // 执行你的逻辑 } } }
方案三:触发器+角度校验
用触发器模拟聚光灯的照射范围,玩家进入触发器后再判断是否处于有效照射角度,减少不必要的计算。
- 创建聚光灯的子物体,添加
CapsuleCollider并调整尺寸匹配聚光灯圆锥范围,勾选Is Trigger; - 挂载以下脚本:
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
相关产品推荐
相关产品推荐

