Unity C#中重构不同类相似函数以避免代码重复的方法
重构Unity中检测最近目标的重复代码
你的问题核心就是逻辑完全一致,仅目标类型和检测层不同,用泛型就能彻底解决代码重复问题,之前泛型用不好大概率是没结合Unity的泛型API,或者没把可变参数抽出来。直接上可行方案:
1. 泛型核心方法
把重复逻辑抽成一个泛型函数,同时传入检测层(因为敌人和友好目标肯定用不同层),泛型约束确保目标类型是Unity组件:
// 泛型方法,T代表目标类型(Enemy/FriendlyTarget) public Transform DetectClosestTarget<T>(Character character, LayerMask targetLayer) where T : Component { Collider[] colliders = Physics.OverlapSphere(character.transform.position, fightingDistance, targetLayer); if (colliders.Length == 0) { return null; } Transform closestTarget = null; float minDistance = Mathf.Infinity; Vector3 characterPos = character.transform.position; foreach (Collider collider in colliders) { // 用Unity泛型GetComponent直接获取目标类型,无需as转换 T target = collider.GetComponent<T>(); if (target == null) continue; float distance = Vector3.Distance(characterPos, target.transform.position); if (distance < minDistance) { minDistance = distance; closestTarget = target.transform; } } return closestTarget; }
2. 调用示例
原来的两个函数直接调用这个泛型方法就行,不用再写重复逻辑:
// 检测最近敌人 public Transform DetectClosestEnemy(Character character) { return DetectClosestTarget<Enemy>(character, enemyLayer); } // 检测最近友方目标 public Transform DetectClosestFriendly(Character character) { return DetectClosestTarget<FriendlyTarget>(character, friendlyLayer); }
关键说明
- 泛型约束
where T : Component:确保T必须是Unity的Component子类(Enemy和FriendlyTarget肯定满足,因为它们是挂载在GameObject上的组件) - 用
GetComponent<T>()替代as转换:类型更安全,代码更简洁,避免无效转换的空值问题 - 抽离
targetLayer参数:原来的两个函数用不同层,必须作为参数传入,不然泛型方法无法区分检测范围 - 补全了找最近目标的完整逻辑:你原来的示例代码里foreach循环没写完,这里补上了距离计算和最近目标筛选的核心逻辑
内容的提问来源于stack exchange,提问作者Alex Grossi
相关产品推荐
相关产品推荐

