Instantiation, destruction, and cooldowns

After the hectic a yesterday, I come back determined and focused on the goal. With my new schedule and my new article-writing workflow. Let’s get on to today’s challenges!

Challenges

Destroy lasers
Offset the laser trajectory
Weapon cooldown system
Enemy behavior
Destroying the enemy

Destroy lasers

Problem: Whenever an object is instantiated in Unity, it will remain in the scene and eventually clutter the hierarchy. To remedy this, objects must be destroyed once they have completed their purpose on our scene.

Challenge: Destroy an object once it has exited the frame/scene.

My solution: With my prior knowledge of the Unity Engine, I know that there is a library-specific code that allows us to destroy objects. However, I can always visit the Unity API to refresh my memory and expand my understanding.

Source: https://docs.unity3d.com/ScriptReference/Object.Destroy.html

When programming my player’s movement, I learned how to keep track of my object in-scene using their position and if statements. In this case, I will keep track of the Y-Axis to know just when this object is out of frame.

transform.Translate(Vector3.up * _speed  * Time.deltaTime);if(transform.position.y >=8){Destroy(gameObject);}

Here you can observe the laser prefab being destroyed when it exits the scene

Offset the laser trajectory

Problem: The initial laser instantiation position causes it clips with the Player Object.

Challenge: Offset the Laser trajectory to avoid clipping

My Solution: Since the laser is instantiated from the Player Object, it shares the same Y value. To avoid the clipping, I needed the laser to spawn just above the Player. I took a look at the Unity viewport to estimate the new Y value and store it in a variable. This arithmetic can be done without a variable but I like this approach better to keep my code as readable as possible.

Vector3 _laserOffset = new Vector3(0, 0.8f, 0);Instantiate(_laserPrefab, transform.position + _laserOffset, Quaternion.identity);

Note: The prior Gif was taken when this challenge was already completed, in it, you can observe that there is no clipping.

Weapon cooldown system

Problem: The laser is firing too frequently, much more than necessary.

Challenge: Create a cooldown system that allows for a better-paced firerate.

My Solution: This was probably the toughest challenge for me today, so I tried to relate the problem to the games I play that have a cooldown, and it led me to think about how some of those games have a stat for fire rate, which indicates how fast the weapon shoots. However, I was still unsure on how to word my research to the Unity API, instead, I checked the definition for the word “Fire rate” to further break down what exactly I needed to turn my attention to. It proved helpful as the definition states “The number of rounds fired per weapon per minute”. It let me know that what I needed to focus on was time.

I needed a way to measure when the next shot can be fired in context to the time amassed since the last shot.

Variables

The value for the variables had a bit of trial and error to get the rate to a comfortable standing.

private float _fireRate = 0.15f;[SerializeField]private float _nextShot = 0.5f;

Implementation

_nextShot = Time.time + _fireRate;

Here you can see how the _nextShot value rising in proportion to the fire rate and time.

Enemy behavior

Problem: The enemy cannot be static in the scene, and its movements should not be predictable.

Challenge: Make the Enemy Object descend, then respawn at a random X position when it reaches the bottom of the screen.

My Solution: Since I have previously programmed a calculator which used random values to calculate a GPA, I already knew exactly what to do in order to randomize the spawn of the Enemy. Furthermore, the movement logic has been seen in the other objects within the scene. All I had to do was relate both topics to one another and apply them.

I decided to treat the randomized X position as a variable to make the code as readable as possible.

transform.position += Vector3.down * _speed* Time.deltaTime;if(transform.position.y <=-5f){float _randX = Random.Range(-11.3f, 11.3f);transform.position = new Vector3(_randX, 7f, 0f);}

I will show the result of the prior code in my next challenge to wrap up the enemy section of today’s progress log.

Destroying the enemy

Problem: The Enemy Object goes through the Laser and Player Objects without any consequences or reactions.

Challenge: Destroy the Enemy when it collides with the Laser or the Player.

My Solution: Collisions deal with physics, as such, some of our game objects need the Rigidbody Component. Namely: The enemy which can collide with the player and the laser, and the laser which can collide with the enemy.

To understand the logic behind collisions, I research the Unity API, where I found that a game object that collides with the object holding the scrip will be referred to as “other”. I also learned the proper syntax for the function that should hold my collision code.

I also learned more convenient ways to keep track of our individual objects through tags.

I made sure that each object was properly tagged. In the event that a proper tag cannot be found, simply create your own.

Now with all the preparations in place, all I needed to do was implement if statements to destroy the appropriate object when the desire conditions are met.

private void OnTriggerEnter(Collider other){if(other.tag == “Player”){Destroy(this.gameObject);}if(other.tag == “Laser”){Destroy(other.gameObject);Destroy(this.gameObject);}

An ambitious writer, and video game narrative designer on a journey to become a Unity Game Developer, and Sofware Engineer.