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

Unity2D弓箭脚本一击多敌问题:如何实现单次仅命中一个目标?

解决Unity2D塔防弓箭单次仅命中一个敌人的问题

核心问题出在:重叠的敌人会同时触发弓箭的碰撞检测,导致一箭触发多个敌人的掉血逻辑。以下是两种简单有效的解决方法:

方法一:用标记变量限制触发次数

修改弓箭脚本,添加布尔变量标记是否已命中目标,确保仅处理一次碰撞:

private bool hasHit = false; // 新增:标记是否已命中目标

void Start()
{
    target = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Transform>();
}

void Update()
{
    transform.position = Vector2.MoveTowards(transform.position, target.position, speedProjectile * Time.deltaTime);
}

private void OnTriggerEnter2D(Collider2D collision)
{ 
    // 仅当未命中过目标时处理碰撞
    if (!hasHit && collision.gameObject.CompareTag("Enemy"))
    {
        hasHit = true;
        Destroy(gameObject);
    }
}

方法二:命中后立即禁用碰撞体

当弓箭命中第一个敌人时,直接禁用自身碰撞体,避免触发后续重叠敌人的碰撞检测:

void Start()
{
    target = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Transform>();
}

void Update()
{
    transform.position = Vector2.MoveTowards(transform.position, target.position, speedProjectile * Time.deltaTime);
}

private void OnTriggerEnter2D(Collider2D collision)
{ 
    if (collision.gameObject.CompareTag("Enemy"))
    {
        GetComponent<Collider2D>().enabled = false; // 禁用碰撞体,阻止后续碰撞
        Destroy(gameObject);
    }
}

额外优化建议

当前弓箭用GameObject.FindGameObjectWithTag("Enemy")只会获取场景中第一个敌人,若要让弓箭优先攻击最近的敌人,可以遍历所有带Enemy标签的对象,计算距离后选择目标:

void Start()
{
    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
    float closestDistance = Mathf.Infinity;
    Transform closestEnemy = null;

    foreach (GameObject enemy in enemies)
    {
        float distance = Vector2.Distance(transform.position, enemy.transform.position);
        if (distance < closestDistance)
        {
            closestDistance = distance;
            closestEnemy = enemy.transform;
        }
    }

    target = closestEnemy;
}

内容的提问来源于stack exchange,提问作者Vasil Kirilov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:03:23