Unity 3D僵尸FPS游戏:武器弹药购买菜单实现方案问询
Hey there! Let’s walk through how to build this ammo shop menu for your zombie FPS—super doable with Unity’s UGUI and some simple script logic. Here’s a step-by-step breakdown:
1. 搭建基础UI菜单
Start by using Unity’s UGUI system to create your shop interface:
- Create a
Canvas(right-click in Hierarchy → UI → Canvas), then add aPanelnamedAmmoShopMenuinside it. Set this panel to inactive by default (uncheck the box in the Inspector). - Add two
Textcomponents to the panel: name them9mmPriceTextandAKPriceText, then set their content to something like*9mm弹药:$50/30发*and*AK弹药:$100/20发*(adjust prices/quantities to fit your game). - Add two
Buttoncomponents below the text, labeledBuy9mmBtnandBuyAKBtn, with button text like "购买9mm弹药" and "购买AK弹药".
2. 实现E键触发菜单显示/隐藏
Create a script (name it AmmoShopController) and attach it to a persistent object like a GameManager or your player character. This script will handle input and toggle the menu:
using UnityEngine; using UnityEngine.UI; public class AmmoShopController : MonoBehaviour { [SerializeField] private GameObject ammoShopMenu; [SerializeField] private Text playerMoneyText; // Optional: display current money void Update() { // Toggle menu when E is pressed if (Input.GetKeyDown(KeyCode.E)) { bool isMenuActive = !ammoShopMenu.activeSelf; ammoShopMenu.SetActive(isMenuActive); // Optional: Pause game and unlock cursor when menu is open Time.timeScale = isMenuActive ? 0 : 1; Cursor.lockState = isMenuActive ? CursorLockMode.None : CursorLockMode.Locked; // Optional: Update money display when menu opens if (isMenuActive) { UpdateMoneyText(); } } } private void UpdateMoneyText() { if (playerMoneyText != null) { playerMoneyText.text = $"当前货币:${PlayerInventory.Instance.playerMoney}"; } } }
Don’t forget to drag your AmmoShopMenu panel (and optional money text) into the script’s Inspector fields.
3. 管理玩家弹药与货币数据
Use a singleton script to keep track of the player’s resources—this makes it easy to access data across your game. Create PlayerInventory.cs:
using UnityEngine; public class PlayerInventory : MonoBehaviour { public static PlayerInventory Instance; public int playerMoney = 500; // Starting money public int pistolAmmo = 60; // Starting 9mm ammo public int akAmmo = 40; // Starting AK ammo void Awake() { // Ensure only one instance exists if (Instance == null) Instance = this; else Destroy(gameObject); DontDestroyOnLoad(gameObject); // Keep across scene loads if needed } }
Attach this script to an empty GameObject named PlayerInventory in your scene.
4. 实现购买逻辑
Add these purchase methods to your AmmoShopController script, then bind them to your buttons in the Inspector:
// Define your ammo prices/quantities as constants private const int PISTOL_AMMO_PRICE = 50; private const int PISTOL_AMMO_QUANTITY = 30; private const int AK_AMMO_PRICE = 100; private const int AK_AMMO_QUANTITY = 20; public void BuyPistolAmmo() { if (PlayerInventory.Instance.playerMoney >= PISTOL_AMMO_PRICE) { // Deduct money and add ammo PlayerInventory.Instance.playerMoney -= PISTOL_AMMO_PRICE; PlayerInventory.Instance.pistolAmmo += PISTOL_AMMO_QUANTITY; // Update UI and give feedback UpdateMoneyText(); Debug.Log($"购买成功!当前9mm弹药:{PlayerInventory.Instance.pistolAmmo}"); // Optional: Play a success sound or show a popup } else { Debug.Log("资金不足!"); // Optional: Play an error sound or show a warning } } public void BuyAKAmmo() { if (PlayerInventory.Instance.playerMoney >= AK_AMMO_PRICE) { PlayerInventory.Instance.playerMoney -= AK_AMMO_PRICE; PlayerInventory.Instance.akAmmo += AK_AMMO_QUANTITY; UpdateMoneyText(); Debug.Log($"购买成功!当前AK弹药:{PlayerInventory.Instance.akAmmo}"); } else { Debug.Log("资金不足!"); } }
To bind the methods: select each button in the Hierarchy, find the OnClick() event in the Inspector, drag your AmmoShopController object into the slot, then select the corresponding method (e.g., BuyPistolAmmo).
5. 额外优化 Tips
- Lock player input when menu is open: In your player movement/shooting scripts, add a check at the start of update methods:
if (AmmoShopController.Instance.ammoShopMenu.activeSelf) return;to prevent actions while the menu is up. - Real-time ammo display: If you want to show current ammo counts in the shop, add text elements and update them when the menu opens, similar to the money text.
- Visual feedback: Add UI animations (like a fade-in for the menu) or particle effects when purchases succeed to make the shop feel more responsive.
内容的提问来源于stack exchange,提问作者Jisimni Josh

