- Home /
Gun State Machine
Hi, all!
I have several guns, all instances of the aptly-named 'Gun' class.
This data is used by my space ship, which finds out which gun is active and fires the appropriate bullet, plays the appropriate sound, so on and so forth.
BUT some of these weapons require functionality outside of the reach of a simple script like the one attached to my ship.
For instance:
When a gun is not firing, it is slowly building up ammo. This even occurs when the player does not have it out.
Some guns require a charging period or have special sounds / effects on Entrance and Exit
Some guns build up Overheat, & need to shut down when that limit is reached
For these reasons, I would deem it appropriate to have a State Machine for each gun with the following states:
Active (Drawn by player)
Dormant (Or Idle)
Firing
A note: This could possibly be whittled down to just 'Dormant' and 'Firing', depending on what later functionality may call for. My point here is that it would be a very simple state machine
This would allow me to provide full and diverse functionality for each weapon.
I all ready have a State Machine on my Ship.
My question here is one of practice.
Would it be good to somehow make the State Machine a class function? How would this be done?
If not, what would be the best way of going about creating this State Machine for each weapon?
Should I have 1 Script called 'Gun State Machines', or what?
Just some things you should know before answering this (They might help)
You can only have 3 out of the 8 guns with you at once
Only 1 gun can be drawn / fired at once
I am working in UnityScript
The Guns themselves are not GameObjects; just classes of data that contain information like Damage, Ammo Cost Per Bullet, Time Between Shots, etc.
I really hope I can get some answers or at least some helpful advice. Thanks!- YA
Answer by Alec Thilenius · Dec 19, 2012 at 07:53 AM
Your question is very vague, so i'll do my best.
There are two good ways I see to get at this. One is to use OOP, and create an inheritance hierarchy, with "Gun" at the top. The Gun script is a mostly empty class that has virtual functions like "OnFire" "OnDormant". Then you have a "Phaser" script that inherits from "Gun". Ill leave the finer points of OOP to further reading.
Unity promotes a component based programming paradigm though. Staying with that, I would recommend actually create a prefab for each weapon, and writing a bunch of different scripts that control a tiny peace of the gun. One script keeps track of things like Ammo, another does nothing by just add to the ammo when you are dormant, another 'fires' the weapon. You can then make different weapons by simply attaching different scripts to the prefab.
Update:
The speed that modern computer run at will take your breath away, even more so when you start getting into GPU programming (HLSL). Speed should be the last thing you worry about (Literally). I performance problem doesn't exist until you see it affecting frame rates.
In programming like this what you want to do is 'compartmentalize' everything. You want each "gun" to be self contained, and have no dependencies on anything else. Unity3D (Like most engines) is component based. You make a self contained entity in what Unity calls a GameObject. Each object in the game can behave differently depending on what scripts are attached to it. I would recommend making an empty game object for each gun, and parenting them all to the ship. Then you have a bunch of options on how you want to implement the next part. A simple was is simply to write a different script for each gun. Depending on how different each gun is this may actually be a good solution. If all guns share some characteristics (Such as ammo count) then you can write one "AmmoCount" script that does nothing but track how much ammo the gun has. When it is empty, it simple disables all the other scripts attached to the same GameObject (Effectively disabling the gun). Lastly I would have one 'master' script that has a list of all the guns attached to the ship. It is responsible for sending commands to the gun scripts like "The player is shooting". And it will send it to the correct gun depending on what weapon you have selected.
Speed should be the last thing you worry about, especially if you are new to coding.
But wouldn't such a large amount of Updates hamper the processor? Plus, I don't see how I could make each gun a Prefab besides making them empties. The ship reads what the currently drawn gun is, then when the player clicks, if there is ammo, the ship fires the appropriate bullet and plays the appropriate noise at 1 of 3 specified locations around it as empties (Gun L, Gun C, and Gun R).
I do have a 'Gun' class with no functions, but it would be extremely easy to simply write an extension for each weapon. The only downfall to this is that I cannot call it dynamically and there'd be some massive Switch statements in there :\
Or maybe I don't understand what you are saying?
What would be the advantage of having a script for each kind of weapon that inherits from Gun? What would be my next step? Sorry to bombard you. I'm a little new to these concepts.
If I were to follow your approach, I would actually still need to keep the Gun Class, simply because the game has upgrades in it and this data is also stored in the class (For instance, you can decrease the amount of ammo per shot by upgrading it).
Some problems:
Wouldn't this require me to potentially write massive amounts of duplicate code for simplistic functions like shooting?
Or are you implying that I should have separate functions that are pertinent to guns be in separate scripts, but any functions that might be dependent on one another should be contained in one script? Sorry. You seem to be very knowledgeable about this and I'm just trying to ferret out some answers via abusing you. :D
I understand the wisdom behind this approach, but interestingly enough, all examples / tutorials I've seen over the years in Unity do not have their games comprised in such a fashion.
Oh, wait. You said the guns should be entirely self-contained. Well that is a problem. How do I know when I should make something independent or not? It would be nigh impossible to code a game with no dependencies. Even the ball in Pong relies on the paddles.
And when you say GameObject you definitely do NOT also mean any instantiated objects of a class, do you?
Your answer
![](https://koobas.hobune.stream/wayback/20220613085633im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Play Audio While Button is Held Down 1 Answer
Respawning script question. 1 Answer
Array Problem - Error Code BCE0022 1 Answer
Grid Creation from Center 2 Answers
Saving an Object of a Class 1 Answer