My journey becoming a Unity game developer: Enemies attacks Player
Objective: Create a specific Enemy Laser object using a Prefab Variant of the Player’s Laser. Then, position the lasers in front of the Enemy’s ship to shoot from in a downward direction. Also, will differentiate between the Player’s lasers and the Enemy’s lasers through code, and have the enemies lasers damage the Player whenever they get hit. Finally, will prevent the enemies from destroying one another by using Layers and the Physics2D Layers Collision Matrix.
To start if you’re using the Laser prefab the Player shoots for the Enemy’s laser this will not be a problem. I chose to create a Laser Prefab Variant to be specifically for all enemies. With this Prefab Variant we can modify it to be different from its parent Laser showing it belongs to an enemy. Remember that any changes made to the parent Laser will also affect the Enemy Prefab Variant Laser.
Inside the Enemy Container under the Spawn Manager object, add the Enemy prefab so we can see the Enemy’s ship onscreen. We’re also doing this to prevent any World Space issues when applying the laser’s position to the Enemy’s ship as this is where all enemies will be spawning from.
With the Enemy object as a Parent, add the Enemy Laser prefab as a child to the Enemy object. Make sure to Reset the Transform Positions to zero making it positioned to the Enemy object.
Duplicate the Enemy Laser object to have 2 lasers onscreen. Check to make sure the Transform positions are set to zero.
Position the lasers in front of each of the ship’s fire nozzle. Use the Copy Position from the position of the 1st laser positioned, and Paste Position the values to the 2nd laser.
Change the lasers names to something like Left_Laser and Right_Laser to give us control over each laser if need be.
Drag the Enemy Laser container object with its children lasers into the Prefab folder making it a prefab.
In the LaserBehavior script, create a variable name isEnemyLaser to check if its True or False. Set the variable to False. Inside the Update() function, check IF the isEnemyLaser variable is False. If so, we will use the MoveUp() method which has the Laser’s movement from the Player’s perspective. Else, we will use the MoveDown() method which will have the Laser’s movement from the Enemy’s perspective.
Take all of the code for the Player’s laser movement from the Update() function and place it in this MoveUp() method.
Copy the code from the MoveUp() function, and place it in the MoveDown() method. Change the Translate() movement from Vector3 Up to Down. Also, change the IF condition of transform.position.y ≤ from 8f to -8f. These changes will now have the Enemy’s lasers move downward, and be destroyed when they are less than -8 meters down the screen.
Under the MoveDown() method, create a Public Void method name AssignEnemyLaser() which will set the isEnemyLaser variable to True. This method will be used to activate the Enemy’s lasers when fired.
Also, create an OnTriggerEnter() method to check IF the other object colliding into the Enemy’s lasers is the Player using the Player’s tag. Plus, check IF the isEnemyLaser variable is set to True. If both conditions are true, get the Player’s script component. NULL check IF the Player’s script component is active, and use the Player’s Damage() method to inflict damage to the Player from colliding into the Enemy’s lasers.
In the EnemyBehavior script, create variables for the fireRate, canFire, enemyLaserPrefab game object, and a enemyLaser game object variable to Instantiate the enemyLaserPrefab. I added optional variables of minFireRate and maxFireRate to give me flexibility in adjusting the Random Range the enemies will be able to shoot at the Player. Also, I can use this script with other new enemies created and give them different Random Ranges to shoot at the Player.
Add the new EnemyLaser() method into the FixedUpdate() function. Then, inside the Void EnemyLaser() method, check IF the game’s Time is greater than the canFire value. If so, fireRate will be set to a Random Range of minFireRate and maxFireRate which will be 3 to 7 seconds. The canFire variable will be set to game Time + fireRate to create a delay in shooting the next lasers.
The enemyLaser variable will Instantiate() the enemyLaserPrefab at the ship’s position with no rotation. Next, we will create a new Array variable name lasers that will Get the LaserBehavior script Components in each enemyLaser Children game objects.
We will use a FOR loop to increment through each laser in the lasers Array, and use the AssignEnemyLaser() method to set each laser to be an Enemy Laser.
The code in the FixedUpdate() function will be placed into a new VOID method name EnemyMovement() which will then be placed inside the FixedUpdate() function to handle the Enemy’s movement in the game.
If you want to keep the enemies from shooting each other, 1st create a new LAYER name Enemy for the Enemy prefab. Add this Enemy Layer to the Enemy Laser container and All its Children. Second, go to Edit<-Project Settings, and select Physics2D. Go down to the Layer Collision Matrix and deselect the Enemy on Enemy layer to prevent any collisions between the Enemy ships and lasers. Do the same thing thing for the regular Physics project setting as well just in case since we’re using Vector3.
Select the Enemy prefab, drag the Enemy Laser container prefab into the Enemy Laser Prefab slot and if you’re using the minFireRate and maxFireRate add the range values you want the enemies to shoot between.
Enemies are moving downward and shooting lasers between the Random Range set. Also, the enemies lasers are not destroying each other when they shoot.