Unity3D 如何查找距离角色与瞄准指示器连线最近的玩家
Unity3D 瞄准辅助最近目标功能实现
核心逻辑为计算所有敌方目标到瞄准射线的垂直距离,筛选出距离最小的目标即可。
1. 构造瞄准射线
你无需额外获取瞄准指示器的世界坐标,直接以射击发起方位置为起点,主摄像机正前方为方向生成射线即可,刚好匹配屏幕中心瞄准指示器的指向:
// 替换为你自己的射击发起位置,比如枪口坐标也可以 Transform shooterTrans = yourPlayerCharacter.transform; Ray aimRay = new Ray(shooterTrans.position, Camera.main.transform.forward);
2. 实现点到射线的距离计算方法
利用向量叉乘的几何特性计算垂直距离,Unity 已有原生API支持:
// 输入瞄准射线、目标点坐标,返回目标到射线的垂直距离 float CalculateDistanceToRay(Ray ray, Vector3 targetPos) { Vector3 crossVec = Vector3.Cross(ray.direction, targetPos - ray.origin); return crossVec.magnitude / ray.direction.magnitude; }
3. 遍历筛选最近目标
遍历所有敌方玩家,排除己方单位,结合你自定义的判定阈值筛选最终目标:
// 自定义判定参数:最大允许距离、最大允许夹角 const float MAX_ALLOWED_DISTANCE = 8f; const float MAX_ALLOWED_ANGLE = 15f; GameObject nearestTarget = null; float minDistance = MAX_ALLOWED_DISTANCE; foreach (GameObject enemy in allEnemyList) { // 跳过已经死亡的单位,可根据你的业务逻辑调整过滤条件 if (enemy.GetComponent<CharacterState>().isDead) continue; Vector3 enemyPos = enemy.transform.position; // 计算垂直距离 float currentDistance = CalculateDistanceToRay(aimRay, enemyPos); // 计算目标和瞄准方向的夹角,避免误选身后的目标 float angle = Vector3.Angle(aimRay.direction, enemyPos - shooterTrans.position); if (currentDistance < minDistance && angle < MAX_ALLOWED_ANGLE) { minDistance = currentDistance; nearestTarget = enemy; } } // 最终判定 if (nearestTarget != null) { // 这里可以加一层障碍物检测,避免穿模判定伤害 // if (Physics.Linecast(shooterTrans.position, nearestTarget.transform.position, obstacleLayer)) return; nearestTarget.GetComponent<Health>().TakeDamage(damageValue); }
可选优化点
- 可以把距离阈值和角度阈值做成可配置参数,根据不同武器调整,比如狙击枪的阈值更小,霰弹枪的阈值更大
- 目标数量较多时,可以先做范围过滤,只计算和你距离在有效射程内的目标,减少性能消耗
内容的提问来源于stack exchange,提问作者Giorgi Abashidze
相关产品推荐
相关产品推荐

