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

塔防游戏WaveSpawning调用MoneyPump的GiveMoney函数问题求助

问题描述

我是编程新手,正在制作塔防游戏,希望实现每波敌人被击败后,所有MoneyPump塔执行GiveMoney()函数增加可配置金额的功能。原本打算在WaveSpawning脚本里调用该函数,但碰到静态相关问题无法解决,附上相关代码片段恳请帮助。

WaveSpawning代码片段

void Update()
{
    if(spawningWave){return;} 
    if(GameManager.gameOver){enabled = false; return;}

    maxWavePlayTime -= Time.deltaTime;

    if(enemiesAlive > 0 && maxWavePlayTime >= 0f)
    {
        return;
    }

    if(waveIndex == waves.Length && !spawningWave)
    {
        gameManager.LevelWon();
        this.enabled = false;
        return;
    }

//THE IDEA IS TO CALL HERE THE MONEY PUMPS 1 TIME


    if(Countdown <= 0f )
    {
        Stats.WavesSurvived++;
        waveToDisplay = waveIndex + 1;
        WaveIndexDisplay.text = "Wave " + waveToDisplay.ToString();
        spawningWave = true;
        StartCoroutine(SpawnWave());
        Countdown = WaveCounter;
        maxWavePlayTime = StartmaxWavePlayTime;
        return;
    }
}

MoneyPumps代码片段

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

public class MoneyPump : MonoBehaviour
{
    public int moneyEveryRound = 25;
    public static bool giveMoney = false;

    public void GiveMoney()
    {
        Stats.Money += moneyEveryRound;
    }
}

炮塔生成相关代码

  1. TurretBluePrint定义
[System.Serializable]
public class TurretBluePrint
{
    public GameObject prefab;
    public int cost;
    public GameObject upgradedPrefab;
    public int upgradeCost;
    public int SellDivider;
}
  1. 商店选择MoneyPump逻辑
public class Shop : MonoBehaviour
{
    public TurretBluePrint LaserBeamer;
    public void SelectMoneyPump()
    {
        Debug.Log("Money Pump Purchased");
        BuildManager.SelectTurretToBuild(MoneyPump);
    }
}
  1. BuildManager选择炮塔方法
public void SelectTurretToBuild (TurretBluePrint turret)
{
    turretToBuild = turret; 
    DeselectNode();
}
  1. 节点点击生成炮塔逻辑
public class Node : MonoBehaviour
{
...
void OnMouseDown()
...
BuildTurret(buildmanager.GetTurretToBuild());
...
}

public class BuildManager : MonoBehaviour
{
...
    public TurretBluePrint GetTurretToBuild()
    {
        return turretToBuild;
    }
...
}
  1. 炮塔实例化代码
void BuildTurret(TurretBluePrint blueprint)
{
...
turretBlueprint = blueprint;
GameObject _turret = (GameObject)Instantiate(blueprint.prefab, 
GetBuildPosition(), Quaternion.identity);
...
}

解决方案

你遇到的核心问题是无法定位所有已生成的MoneyPump实例并调用它们的GiveMoney方法,这里提供两种简单可行的实现方式:

方法一:直接查找所有MoneyPump实例(简单快捷)

在WaveSpawning脚本你标注的THE IDEA IS TO CALL HERE位置,添加以下代码即可:

// 遍历场景中所有MoneyPump实例,调用GiveMoney
MoneyPump[] allMoneyPumps = FindObjectsOfType<MoneyPump>();
foreach (MoneyPump pump in allMoneyPumps)
{
    pump.GiveMoney();
}

这种方式无需额外逻辑,适合新手快速实现需求。唯一需要注意的是,若场景中物体数量极大可能有轻微性能开销,但塔防游戏中炮塔数量有限,完全可以忽略。

方法二:维护全局MoneyPump列表(高效可扩展)

如果后续需要对MoneyPump做更多统一管理,推荐提前维护一个静态列表:

  1. 修改MoneyPump脚本,让实例自动加入/移除列表:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoneyPump : MonoBehaviour
{
    public int moneyEveryRound = 25;
    // 静态列表存储所有MoneyPump实例
    public static List<MoneyPump> allPumps = new List<MoneyPump>();

    void Awake()
    {
        allPumps.Add(this);
    }

    void OnDestroy()
    {
        allPumps.Remove(this);
    }

    public void GiveMoney()
    {
        Stats.Money += moneyEveryRound;
    }
}
  1. 在WaveSpawning的目标位置调用:
// 遍历全局列表调用方法
foreach (MoneyPump pump in MoneyPump.allPumps)
{
    pump.GiveMoney();
}

这种方式性能更优,且方便后续对所有MoneyPump做批量操作(比如统一升级、禁用等)。

额外提示

  • 你之前定义的public static bool giveMoney = false如果没有实际用途,可以直接删除,避免代码冗余。
  • 确保你选择的调用位置确实是每波敌人全灭、即将进入下一波的时机,避免重复触发或漏触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:25:18