Find yourself writing the same code over and over and over with the same variables? If so then it is time to convert your code to base into a Class, Behavior, Scriptable Object, or Method. In my case with using power ups in the Player class I was repeating the same 2 variables( different names) with the same 5 lines of code in the Awake Method.
Classes are nothing new to programming. In Unity Behaviors are a special type of Class that Unity calls Update, Awake, Start, and other Methods at specific times.
If you want to use your own class in Unity there is one rule that you must follow. That is if you want be able to assign the Parameters in Unity Inspector you must mark the Class with the
Doing it this way reduces 35 Lines of code in the Player Behavior to 10. This is 2 Variables and 5 Initialization per power up to 1 Variable and 1 Initialization. This makes it less error prone, i.e. missing something on one of the power ups and it not working. It allows me to focus on the functionality of the Power Up instead of the Boiler Plate Code.
Secondary Fire Power Up
I already Have a Triple Shot Power Up. I am going to add a homing laser that will look for the closest enemy and hunt is down to destroy it.
The implementation of this is going to be the same as the Triple Shot, the difference will be an added script to the laser prefab that will control its movement.
I changed the Fire Laser Method drastically after I removed ammo. If the Triple Shot and Homing Laser are not active or both prefabs are no assigned I fire the regular laser and return.
If the Triple Shot is active I check to see if there is a prefab that can be instantiated. If there is a prefab I spawn the triple shot. If there is not a triple shot prefab I fire the regular laser only if the Homing Laser is not active. I do the same check with the Homing Laser. I decided to allow the Player to have more then one fire power up active at a time but the regular laser should only be fired if there are no power ups active. I decided not to make it so the Player can not defend themselves if the prefab did not get assigned.
The most complicated Power up to Implement is the Fire Power Ups. These power ups are now 5 times easier to add with the new Power Up Class, use the boiler plate to activate it and I can focus on the logic and implementation.
Creating The Prefab
I used the Player Laser Prefab as the Base to create the Homing Laser. I made it bigger by changing the scale (2, 0.5, 0.5). I removed the Moveable Component because this will have a custom movement code.
I Changed the Color so the Player can tell this is a completely different type of laser.
I ended up changing the Scale (1, 0.25, 0.5) to make it fit in the player sprite. I applied the changes I made to the prefab.
I Created the Seek Target Behavior to add, and added it.
I Am going to need a target to move the Homing Laser towards. I will be finding all the game objects in the scene with the “Enemy” tag. I need a speed to move at. I Give it a time to live, if this time is set to zero it will live forever. I need the Game Move Direction just in case there is no target found, it will have a direction to move in. In the Start Method I check the time to live if it is greater the zero then i tell Unity to Destroy the Game Object after the time to live as passed.
To find the all the Enemies in the Game I use Find Game Objects With Tag this gives me an array of active Game Objects in the Scene tagged
tag, if there are none it returns an empty array. I then use the Order By Method (See Stack Flow for detail, basically Order by is a cleaner way of doing it the the sort method) to Sort all of the Enemies by their distance from the laser. To get the distance I use the Distance Method which returns a
float distance between 2 vectors. I then use the First Or Default to get the first Game Object in the Array, if the Game Object is not Null then I set the Target to the Game Objects Transform.
Making Sure that it works.
This can be combined into one line of Code.
Now if I have a target I can Move Towards it. If I don’t have a target then I will just move in the game move direction.
This works and my laser is moving in the correct direction.
I need to make it rotate so it faces the target.
I use Rotate Towards which Rotates a rotation
to (created rotation) at a
speed(movement speed frame rate independent). To create the rotation to rotate to I use Look Rotation which
creates a rotation with the specified
It does rotate towards the target, but only slightly.
It rotates but not fully. To narrow it down to which portion of the code is causing the issue, got ride of the rotate towards and set the rotation to just the look rotation.
The Rotation is being created on the X and Y, I need it to rotate on the Z.
I can add the up direction to be forward.
This gives me a rotation on the Y and Z axis. I can not see the laser in game because of the y axis.
I modified the rotation that I wanted to just be on the z axis.
Now I can add the Rotate towards back in.
They are rotating just at a slow speed.
To fix that problem I added a rotation speed in and set it to 60.
I think the speed is a little slow but it is hard to tell since they are rotating backwards.
To fix the rotation I just have to change which direction is up. The cameras forward axis is in the Z so the up direction in the game is -Z
Now that things are working correctly I adjusted the Speed and Rotational Speed until I was happy with the results. I then Changed the Scale and The Color until I got something I was Happy with.
Now the original issue with the original code I started with was the rotation speed and the direction that I was using as the up direction. But there is no good way to adjust the Y and X rotation values to keep the Laser from disappearing on screen. The Further away the more noticeable it is.
For an interesting effect
There are all kinds of different movement code that I could add or do to get different effects.