Secondary firing! How to add heat seeking missiles (and research!)
Sometimes when you are coding you run into a.. snag. This was one of those cases where I ran into a snag. Like a HUGE snag.
I wanted to give the player an extra attack. I thought a heat seeking missile would be awesome. And it is. Adding it? Not so awesome! But, it can be done. Read on…
So adding the main code wasn’t difficult as I had already added the laser. So instantiating the missile was no problem, making it fly was no problem. Having it chase the enemy.. problem!
First, let me tell you that when you are programming you are going to hit these snags. The one thing you need to understand is that there are A LOT of ways to solve it. A quick google for my problem gave me hundreds of pages of tutorials/message board instructions. Again, the problem was taking the one that fit my code… In this case, a very VERY nice tutorial is Brackey’s and you can find it here.
Seriously, go watch it. I won’t get into a lot of explanation here as I’m still trying to wrap my head around some of the code and I think I would do you an injustice by trying to explain it.
Another kudo’s to Alex who is also working at GameDevHQ and helped me over the final hump. You can read his medium article on the topic here.
I’ll explain how I implemented mine but not the basics like creating the prefab etc.
Once I had my missile prefab I added a missile script and attached it to the missile, adding this code to give my missile movement.
A brief breakdown — I created a new method that would calculate movement of the missile and called it in the FixedUpdate (you should always use a FixedUpdate when working with physics.
- So it checks if the target (this is the target the missile chose) it will track the position by setting a direction variable to the transform of the target. Then I get the rigidbody velocity and set it to rotate towards the enemy by using rotateAmount and rotateSpeed that I set up.
- Then I created a new missile target that just gets the transform of the enemy and set it to the _target variable.
- Finally, I noticed that the missile was just flying everywhere if it didn’t collide with something and looked crazy. So I set up a Coroutine that would make the missile destroy itself after 4 seconds.
To get the target — the heat seeking part of this implementation I created a method inside of the Player script that would do a lot of math (that I hate). This is the part you need to watch the Brackey’s video to understand. But the basics of it..
Created a transform variable that would store the best enemy target transform and set it to null at the beginning. It then takes the players current position and starts a for each loop that will choose potential enemy targets and assign their transform to bestTarget. Brackey’s explains it so much better…
Next up I set up the powerup that would give the player 5 missiles. I was originally going to set a time limit to the powerup but I figured giving the player a set number was better.
I was having difficulty adding this to my normal powerup spawn routine because I wanted it to be a little more rare, so I created my own script for it that just held the code that would destroy it if it left the screen or collided with the player. It also called the Missile() function that I created in the Player script that would add the missiles.
Once I did that I just added a few lines of code to the spawn manager that would set a random number and make it a bit more rare this would be called:
As you can see I just set a randomMissile int to choose a random number between 0–5 and then if the randomMissile variable was a 1 it would instantiate the powerup. The one thing I had to make sure to do was give it it’s own spawn position because we didn’t want it to spawn on top of the other powerups.
With that done I now had to set the code to launch the missile. An easy if statement inside the player update just checked if the player pressed E and a delay on the fire as well as checking if the player had missiles and it would call the FireMissile method I create later.
Last 2 methods I created was the Missiles() that would be called when the player hit the powerup and add 5 to the _missile count and call my UIManager script and add the total to the UI on screen:
Lastly, the actual FireMissile function that is called when the player hits E and has missiles:
So this is where the fun takes place. It assigns an enemy to _enemiesActive gameobject. Then it makes sure the player can’t spam the E key so it gives it a time delay, then subtracts 1 missile and assigns that number to the UI to update on screen missile count.
It will call the GetClosestEnemy function so it has that information and then instantiate the missile for launch calling the MissileTarget to get the closest enemy. Finally it plays a cool missile sound.
A lot going on there as you can see. This took a while, but as I said, Google is your friend. That, and joining a group of coders.. trust me on that last one. This was a hard challenge and I needed a little shove in the right direction here and there. Coding isn’t about knowing it all (although that would be nice!). It’s about having the knowledge to be a good reasearcher.
So, let’s have a look at the missiles in play:
Pretty cool! Notice when it hits the asteroid. I set that up so that if they collide it would explode, but it wouldn’t actively seek the asteroid (heat seeking and all).
Well, I’m moving forward after this difficult implementation! Tomorrow I’m going to add a thruster bar that shows when the player is out of thrusters and it will slow him down.