塔防游戏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; } }
炮塔生成相关代码
- TurretBluePrint定义
[System.Serializable] public class TurretBluePrint { public GameObject prefab; public int cost; public GameObject upgradedPrefab; public int upgradeCost; public int SellDivider; }
- 商店选择MoneyPump逻辑
public class Shop : MonoBehaviour { public TurretBluePrint LaserBeamer; public void SelectMoneyPump() { Debug.Log("Money Pump Purchased"); BuildManager.SelectTurretToBuild(MoneyPump); } }
- BuildManager选择炮塔方法
public void SelectTurretToBuild (TurretBluePrint turret) { turretToBuild = turret; DeselectNode(); }
- 节点点击生成炮塔逻辑
public class Node : MonoBehaviour { ... void OnMouseDown() ... BuildTurret(buildmanager.GetTurretToBuild()); ... } public class BuildManager : MonoBehaviour { ... public TurretBluePrint GetTurretToBuild() { return turretToBuild; } ... }
- 炮塔实例化代码
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做更多统一管理,推荐提前维护一个静态列表:
- 修改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; } }
- 在WaveSpawning的目标位置调用:
// 遍历全局列表调用方法 foreach (MoneyPump pump in MoneyPump.allPumps) { pump.GiveMoney(); }
这种方式性能更优,且方便后续对所有MoneyPump做批量操作(比如统一升级、禁用等)。
额外提示
- 你之前定义的
public static bool giveMoney = false如果没有实际用途,可以直接删除,避免代码冗余。 - 确保你选择的调用位置确实是每波敌人全灭、即将进入下一波的时机,避免重复触发或漏触发。
内容的提问来源于stack exchange,提问作者Lexus
相关产品推荐
相关产品推荐

