I’ve made a very basic 2D game where I have enemies coming in from left to right in waves. I’ve managed to create the wave spawner myself using arrays and a coroutine and it works really well.
I’ve now come to the stage where I want to make a weapon upgrade system. I have searched endlessly through forums and youtube videos for a solution that makes sense to me but have yet to find one.
My question is how should I implement a weapon upgrade system?
As it stands I have a pistol prefab which contains a sprite and a weapon controller script attached to it. I have attached the pistol prefab as a child of my player so that it moves with my player.
I want to add a machine gun and shotgun weapon that my player can use by cylce through.
My first idea was to add all weapon prefabs to my character rig and set them to inactive. I then planned to use an enum in my game controller to update the weapon state, and then set the corresponding weapon object to active depending on the weapon state. I’ve quickly come to find that this is very difficult as there isn’t a particular method for finding inactive objects.
I then looked at just adding all scripts to each weapon and then planned to instantiate them depending on the weapon state, but still wasn’t sure whether this was the right way to go about it.
Right now, I’ve thinking of creating an array of weapons in the game controller, adding each weapon prefab in the inspector, instantiating them according to my enum weapon state and at the relevant player position.
One point to make is that I really wanted to the ability to upgrade the weapons but wasn’t sure how to correctly go about this.
If anyone can point me in the right direction I’d massively appreciate it.
You’re almost there if you combine those ideas. My suggestion is to add all of your weapons as inactive child GameObjects of the player. In your game controller script (on the player itself), define an array that can hold references to these inactive children. This way you don’t have to find them; you can assign the references at design time in the inspector. When the player switches to a different weapon (assuming it’s unlocked to the player), disable all the elements in the array, and then enable just the one active weapon.
By “upgrade system” do you mean unlocking access to new weapons such as machine gun and shotgun? If on the other hand you mean upgrading the capabilities of each weapon (e.g., shotgun to double shotgun to automatic shotgun, etc.) then you could either make each upgrade a separate weapon, or you could add a script to each weapon that has an OnEnable method. In this method, look up the current upgrade state of the weapon and apply the upgrades to it.
I have tried and tested your method and it appears to be working flawlessly.
I have another question which I’m hoping someone can help me with. I have just finished the layout of an upgrade menu using UI components which is in another scene.
I want to be able to buy upgrades depending on my playerBalance. Initially I thought to just make a function in an UpgradeManager script and fill it with either if statements or switch statements, and then use that function in the OnClick method of every button. After doing a few of the different statements its starting to look a bit ridiculous, as I have about 15 different weapon upgrades.
If anyone has made an upgrade menu before? How did you go about it?
Load your upgrade menu scene additively (e.g., using LoadSceneMode.Additive). When the player dismisses the menu, unload the scene.
Write a script that you can attach to each upgrade button. For example, say your player character has a Player class with this info:
public class Player : MonoBehaviour {
public int playerBalance; // Amount of currency available to buy upgrades.
public enum Upgrades { DoubleShotgun, AutomaticShotgun, LaserSight, etc. }
public bool HasUpgrade(Upgrades upgrade) { /*you define this*/ }
public bool BuyUpgrade(Upgrades upgrade) { /*you define this*/ }
...|
Then add a script like this to each button:
public class UpgradeButton : MonoBehaviour {
public Upgrades upgrade; // Assign in inspector.
public int cost; // Assign in inspector.
private Player player;
public void Start() {
player = FindObjectOfType<Player>();
var button = GetComponent<UnityEngine.UI.Button>();
button.interactable = !player.HasUpgrade(upgrade) && player.playerBalance >= cost;
}
public void BuyUpgrade() {
button.interactable = false;
player.BuyUpgrade(upgrade);
}
}
On each button’s inspector, select the upgrade from the dropdown list. Then add an item to the button’s OnClick () event, and assign UpgradeButton.BuyUpgrade(). No ‘if’ or ‘switch’ necessary.