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

如何在非挂载GameObject的脚本中按条件调用非静态方法?

解决方案:事件驱动实现无耦合的敌人生成触发

要实现敌人全灭时自动调用非静态的Spawning方法,同时避免脚本间的直接耦合,最合理的方式是使用事件驱动模式。这种方式下,敌人销毁时仅触发事件,敌人生成脚本监听事件并判断是否需要生成新敌人,完全不需要其他脚本(比如玩家移动脚本)知晓敌人生成脚本的存在。

步骤1:改造EnemySpawning脚本

首先将原脚本改为MonoBehaviour(必须挂载到场景中的GameObject上,比如GameManager对象),添加敌人计数逻辑和事件监听:

using UnityEngine;
using UnityEngine.SceneManagement;
using System;

public class EnemySpawning : MonoBehaviour
{
    public int level = 1;
    private int currentEnemyCount = 0;

    void Start()
    {
        // 初始生成第一波敌人
        Spawning();
        // 订阅敌人销毁事件
        Enemy.OnEnemyDestroyed += OnEnemyDestroyed;
    }

    void OnDestroy()
    {
        // 取消订阅防止内存泄漏
        Enemy.OnEnemyDestroyed -= OnEnemyDestroyed;
    }

    public void Spawning()
    { 
        if (SceneManager.GetActiveScene().name != "Game") return;

        GameObject enemyObject = Resources.Load<GameObject>("BasicEnemy");
        int enemyQuantity = 3 * level;

        int minSpawnX = -3;
        int maxSpawnX = 3;
        int minSpawnY = 2;
        int maxSpawnY = 5;

        for (int i = 0; i < enemyQuantity; i++)
        {
            float xPos = Mathf.Round(UnityEngine.Random.Range(minSpawnX, maxSpawnX));
            float yPos = Mathf.Round(UnityEngine.Random.Range(minSpawnY, maxSpawnY));

            GameObject enemy = Instantiate(enemyObject, new Vector3(xPos, yPos), Quaternion.identity);
            currentEnemyCount++;
        }

        level += 1;
    }

    private void OnEnemyDestroyed()
    {
        currentEnemyCount--;
        // 所有敌人消灭后触发新一轮生成
        if (currentEnemyCount <= 0)
        {
            Spawning();
        }
    }
}

步骤2:给Enemy脚本添加事件触发

在敌人的脚本中定义静态事件,当敌人销毁时触发该事件:

using UnityEngine;

public class Enemy : MonoBehaviour
{
    // 定义静态事件,供外部订阅
    public static event System.Action OnEnemyDestroyed;

    void OnDestroy()
    {
        // 触发事件,通知所有订阅者敌人已销毁
        OnEnemyDestroyed?.Invoke();
    }
}

方案优势

  • 完全解耦:Enemy脚本仅负责触发事件,无需知道EnemySpawning的存在;其他脚本(如玩家移动脚本)完全不需要参与敌人生成逻辑。
  • 非静态方法可用:EnemySpawning的非静态方法可以正常访问level变量。
  • 自动触发:当所有敌人销毁后,会自动调用Spawning方法生成下一波敌人,无需手动调用。

注意事项

  • 确保EnemySpawning挂载的GameObject在场景加载时不会被销毁(如果需要跨场景保存,可添加DontDestroyOnLoad(gameObject))。
  • 必须在脚本销毁时取消事件订阅,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:42:09