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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:43:25