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

Unity PVZ类游戏塔台攻击逻辑Bug求助:多敌人场景异常

PVZ类游戏塔台射击逻辑问题修复方案

我正在开发一款PVZ类游戏,原本期望实现:敌人进入塔台攻击范围时塔台射击,离开时停止射击。但当前塔台持续射击,于是基于碰撞检测实现了相关逻辑,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class attackRange : MonoBehaviour
{
    public towerAttacker towerAttacker;
    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "enemyCollider")
        {
            towerAttacker.shootStart();
            // It will detect once but once too many enemies are present it only counts as 1

        }
    }

    void OnTriggerStay2D(Collider2D collision)
    {
         if (collision.tag == "enemyCollider")
        {
            towerAttacker.shootStart();
        // It detects constantly but makes the object go into rapid fire mode
        }

    }
    void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.tag == "enemyCollider")
        {
            towerAttacker.StopAllCoroutines();
        // Stop when there is no collision detected
        }
    }
}

该逻辑在单敌人场景下正常,但多敌人场景异常:

  • OnTriggerEnter2D仅检测一次,多敌人时仅触发一次射击逻辑
  • OnTriggerStay2D会导致塔台进入快速射击模式
  • OnTriggerExit2D会误停所有协程(只要有一个敌人离开就停止射击,哪怕还有其他敌人在范围内)

修复思路

核心是跟踪范围内的敌人数量,只有当敌人数量从0变1时启动射击,从1变0时停止射击,避免重复触发或误停止。

修复后的AttackRange代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackRange : MonoBehaviour
{
    public TowerAttacker towerAttacker;
    private int enemyCount = 0;

    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("enemyCollider"))
        {
            enemyCount++;
            // 仅第一个敌人进入时启动射击
            if (enemyCount == 1)
            {
                towerAttacker.StartShooting();
            }
        }
    }

    void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("enemyCollider"))
        {
            enemyCount--;
            // 防止数量出现负数(应对碰撞检测异常)
            enemyCount = Mathf.Max(enemyCount, 0);
            // 最后一个敌人离开时才停止射击
            if (enemyCount == 0)
            {
                towerAttacker.StopShooting();
            }
        }
    }
}

配套TowerAttacker类调整

不要直接用StopAllCoroutines(),给射击协程单独引用,避免误停其他协程:

using System.Collections;
using UnityEngine;

public class TowerAttacker : MonoBehaviour
{
    private Coroutine shootingCoroutine;
    public float shootInterval = 1f; // 可在Inspector调整射击间隔

    public void StartShooting()
    {
        // 避免重复启动协程
        if (shootingCoroutine == null)
        {
            shootingCoroutine = StartCoroutine(ShootLoop());
        }
    }

    public void StopShooting()
    {
        if (shootingCoroutine != null)
        {
            StopCoroutine(shootingCoroutine);
            shootingCoroutine = null;
        }
    }

    private IEnumerator ShootLoop()
    {
        while (true)
        {
            // 这里替换成你的实际射击逻辑(比如实例化子弹、锁定敌人等)
            Debug.Log("塔台发射子弹");
            yield return new WaitForSeconds(shootInterval);
        }
    }
}

关键说明

  • 用enemyCount精准控制射击启停时机,彻底解决多敌人场景的异常
  • 替换collision.tag ==为CompareTag(),性能更优且避免空引用风险
  • 移除OnTriggerStay2D,无需持续触发启动逻辑
  • 单独管理射击协程,避免StopAllCoroutines()误停其他协程

内容的提问来源于stack exchange,提问作者Nicole Erasga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:55:16