Unity双阵营炮塔按指定多标签筛选最近敌人的实现问题
双阵营炮塔多标签筛选寻敌解决方案
实现思路
- 无需拆分阵营独立脚本,新增可序列化的标签配置字段,在Inspector面板即可为不同阵营的炮塔直接配置对应的3个敌方标签
- 遍历敌方单位时新增标签校验逻辑,仅对匹配标签的单位做距离计算和锁定判定
- 新增空值校验逻辑,修复无匹配目标时触发空引用异常的问题
完整修改后代码
using UnityEngine; using System.Linq; // 用于标签匹配的Contains方法,不需要Linq可替换为下方的自定义校验方法 using Vector3 = UnityEngine.Vector3; public class TargetLocator : MonoBehaviour { [SerializeField] Transform weapon; [SerializeField] ParticleSystem projectileParticles; [SerializeField] float range = 1.5f; [SerializeField] Transform enemy; // 新增:允许攻击的目标标签数组,在Inspector里配置对应阵营的3个敌方标签 [SerializeField] string[] allowedTargetTags; void Update() { FindClosestTarget(); AimWeapon(); } void FindClosestTarget() { Enemy[] enemies = FindObjectsOfType<Enemy>(); Transform closestTarget = null; float maxDistance = Mathf.Infinity; foreach (Enemy enemy in enemies) { // 标签筛选:不在允许列表内的单位直接跳过 // 不用Linq的话替换为 if (!IsValidTargetTag(enemy.tag)) continue; if (!allowedTargetTags.Contains(enemy.tag)) continue; float targetDistance = Vector3.Distance(transform.position, enemy.transform.position); if (targetDistance < maxDistance) { closestTarget = enemy.transform; maxDistance = targetDistance; } } enemy = closestTarget; } public void AimWeapon() { // 新增无目标判断,避免空引用报错 if (enemy == null) { Attack(false); Debug.Log("未找到匹配目标"); return; } float targetDistance = Vector3.Distance(transform.position, enemy.transform.position); if (targetDistance < range) { weapon.LookAt(enemy.transform.position); Attack(true); } else { Attack(false); Debug.Log("目标超出射程"); } } public void Attack(bool isActive) { var emissionModule = projectileParticles.emission; emissionModule.enabled = isActive; } // 备选:不引入Linq的标签校验方法,不需要可删除 private bool IsValidTargetTag(string tag) { foreach (string allowedTag in allowedTargetTags) { if (allowedTag == tag) return true; } return false; } }
使用步骤
- 脚本挂载到炮塔游戏对象后,在Inspector面板找到
Allowed Target Tags数组,调整数组大小为3 - 左方阵营炮塔填入3个右方敌方单位的标签,右方阵营炮塔填入3个左方敌方单位的标签
- 原有射程、武器节点、投射粒子等参数保持原有配置即可,运行后炮塔只会锁定配置标签范围内的最近敌方单位
内容的提问来源于stack exchange,提问作者505Legion
相关产品推荐
相关产品推荐

