Tower Defense Tutorial – Brackeys – Ep. 06, 07

January 26, 2019

Tower Defense Tutorial

Episode 06 – Turrets

Youtube – How to make a Tower Defense Game (E06 BUILDING) – Unity Tutorial
Youtube – How to make a Tower Defense Game (E07 CAMERA) – Unity Tutorial

By: Brackeys
Ep. 06

This tutorial covers the user interactions with the node spaces. We started with an OnMouseEnter and OnMouseExit methods. These simply changed the color of the node when hovering the mouse over the node object.

A BuildManager script was created and added to the GameManager object in the game to help dealing with building turrets. We want to access this to handle the building of turrets. The BuildManager used a basic singleton pattern. To do this, we created a public static BuildManager variable called instance within the BuildManager script itself. This will effectively reference itself. In the Awake method, we just set instance equal to this.

Building a turret just used the basic instantiation setup again. The only slight difference is that the node script references the BuildManager script to determine what turret to build (will be more useful in the future with different turret types).

SUMMARY

  • OnMouseEnter and OnMouseExit very straightforward Unity methods for dealing with hovering mouse actions.
  • Learn more about Singleton pattern and why it’s useful
  • Basic color change on hover setup: store original color at start; change color during action (i.e. OnMouseEnter); change back to stored original color after event
  • Easy to access public singleton-like class and its methods with the instance = this setup; Just {name of script}.instance.{name of method}()
  • Setting a Color variable as public in Unity editor just lets you select any color with normal color selection palette
Ep. 07

This tutorial focused on creating the camera controller. It was created in sort of an RTS style. This would be down on keypress, using if (Input.GetKey(“w”)), which would then perform a transform.Translate(). Translate is an easy way to move objects without any need for physics.

To go with typical RTS camera movement, we wanted to move the camera around when the player has the mouse cursor around the edges of the screen. We started with Input.MousePosition, which registers the screen position of the mouse relative to the bottom left corner. This method of tracking the mouse obviously varies with the screen size, so it is a good idea to use this in conjunction with references to the screen size (i.e. Screen.height) as opposed to hardcoded values. We didn’t want to require the mouse to be at the complete border of the screen to move the camera, so we added a panBorderThickness variable to subtract from the screen dimension variables to create an area near the border of the camera where the movement would apply.

The camera movement buffer zones become the following:

  • Top: mousePosition.y >= Screen.height – panBorderThickness
  • Top: mousePosition.y <= panBorderThickness
  • Top: mousePosition.x >= Screen.width – panBorderThickness
  • Top: mousePosition.x <= panBorderThickness

We also added a zooming effect. It can feel extra nice if you rotate the camera relative to its zoom. There is an extra amendment to this tutorial for this effect. This will use the scroll wheel. It is treated more similarly to a joystick, where you use Input.GetAxis. You can find the reference name of the mouse scroll wheel in Project Settings -> Input. Finally, to restrict the zooming values, we created a min and max value and used Mathf.Clamp to limit that.

Unity Forum Link – More Information for Nicer Camera Controller

SUMMARY

  • transform.Translate() good for non-Physics based movement
  • Use Screen.Height and Screen.Width with a border buffer to create zones of mouse position to move camera in RTS-style
  • Create min/max values for camera distance so it doesn’t fly away from game

Tower Defense Tutorial – Brackeys – Ep. 05

January 25, 2019

Tower Defense Tutorial

Episode 05 – Turrets

Youtube – How to make a Tower Defense Game (E05 SHOOTING) – Unity Tutorial

By: Brackeys
Ep. 05

This tutorial starts adding the shooting logic to the turrets. It begins with a basic setup to have a fire rate/firing cooldown based on a timer subject to Time.deltaTime. It then gets into some variable organization where they are situated in a way that makes more sense and adds in headers for clarification in the Unity editor. Creating a header just requires this: [Header(“Header Name”)]. This really nicely separates the variables in the editor, as it sections them off along with the title at the top of that block of variables.

The bullets for the turret are created with a basic Instantiation. However, since we want to reference the bullet instantiated in someway, we set it equal to a GameObject variable. This also requires “object casting”, so the instantiation has (GameObject) in front of it. I need to look into object casting.

This required more instances of destroying gameObjects, and again the tutorial adds the return command afterward to make sure to account for the processing time needed to destroy an object. I need to look into proper use of “return” in Unity scripting.

Determining if the bullet hit the target used an interesting method. The vector between the bullet and its target was determined each frame in Update as normal, but instead of using this solely for directional purposes by normalizing it, the distance (magnitude) was used to determine collision. Another variable, distanceThisFrame, was created and was just the bullet’s speed * time.deltatime. This would determine how far the bullet should move this frame. This was compared with that directional vector between the bullet and the target, and if the distance between them was less than the distance the bullet should travel, it was determined the bullet should collide. I think this specifically works better with a “homing” style projectile, since this means the target moving out of the way isn’t really an option anyway, and it constantly wants to update direction anyway.

They created a simple particle effect to go with the bullet collision. They treated this similarly to the instantiation of the bullet. The particle effect was instantiated as a new gameObject variable, and cast as a gameObject. This was then immediately referenced the next line to Destroy it after a time (after its duration basically). This is a good way to keep your scene clean with instantiated particle effects so they don’t linger as gameObject even after they appear to be gone.

SUMMARY

  • Headers are fantastic for keeping public variables organized in the Unity editor.
  • Destroying gameObjects can take processing time, so using return in conjunction can help keep code safe and do what you expect.
  • Look into proper use of “return;” command.
  • Look into “casting to GameObject”
  • Instance particle effects as gameObject variables to reference to easily destroy them so they do not clog scene

Tower Defense Tutorial – Brackeys – Ep. 04

January 24, 2019

Tower Defense Tutorial

Episode 04 – Turrets

Youtube – How to make a Tower Defense Game (E04 TURRETS) – Unity Tutorial

By: Brackeys
Ep. 04

This starts the creation and implementation of the turret objects.

Use OnDrawGizmosSelected to show important editor information when an object is selected. In this case, DrawWireSphere was used and it showed a wireframe of a sphere with a radius corresponding to the range of the turret.

Wanted turret to update to find targets to fire at, so method UpdateTarget was created. This is going to be relatively expensive using distance checks so it was made as a separate “Update” method so we could run it much less than every single frame. This method was then called in Start with an InvokeRepeating call, which lets you set a time to start running, and a time interval to repeat the method.

Rotating the turrets required usage of Quaternions. First, the direction was obtained with a simple Vector3 between the object and target. This was converted to a Quaternion variable with Quaternion.LookRotation(). It was then converted back to an angular measurement, which was another Vector3 variable that took the Quaternion and just applied .eulerAngles to it. Finally, that angular value was passed specifically to the transform’s rotation value as a Quaternion.Euler rotation vector (which we just passed the y portion of our rotation vector to the y portion of this rotation vector). So keep in mind dealing with angular movement may require lots of back and forth with angles and quaternions.

PROBLEMS

There was an issue where the turret rotation was off by 90 degrees, so the tutorial solved this by separating out the prefab and rotating the rotationPoint(partToRotate) that was an empty parent object of the intended object needing rotation by -90. The child/parent relationship was then put back together and the prefab was reassembled. I decided to just add 90 degrees to the y rotation of partToRotate in the script when assigning the rotation and this worked fine. However, when we changed the method to add a Lerp for the rotation, this broke my solution. This makes sense because the Lerp wanted to go between the partToRotate original rotation and the new rotation, neither of which had my additional 90 degrees in it. Then when it would go to assign the new partToRotate.rotation with my additional 90 degrees and go back to Lerp again, the value was then way out of the original range. This gave a crazy looking jittery effect. This has taught me that I don’t understand Quaternions at all and will need to look into those in the future.

Tower Defense Tutorial – Brackeys – Ep. 01, 02, 03

January 23, 2019

Tower Defense Tutorial

Episode 01 – 02 – 03

Youtube – How to make a Tower Defense Game (E01) – Unity Tutorial
Youtube – How to make a Tower Defense Game (E02 Enemy AI) – Unity Tutorial
Youtube – How to make a Tower Defense Game (E03 Wave Spawner) – Unity Tutorial

By: Brackeys
Ep. 01

Created all the nodes in grid that make up the map. Created the ground out of scaled cube objects as well. Added start and end location as simple cubes for now.

Ep. 02

Creating the enemy AI with waypoints. A static transform array was created to contain all of the locations of the waypoints. There was an issue where we got an “index out of range” error because the enemy was looking for another waypoint to go to when it was supposed to be destroyed. It was being destroyed, but since that can take the computer some time to do, it was continuing into the next lines of code before the object was completely destroyed. To solve this, a return; line was added in the if statement for destroying the object to ensure that process finished before doing the rest of the code.

Ep. 03

This was creating the wave spawner for the enemies. The spawner needs a timer to control how often and when it releases waves. The approach used here was a countdownTimer that was reduced by time.deltatime in the update method.

Enemies however were being spawned directly on top of each other all at once for each wave. Coroutines were the choice to resolve this issue. Coroutines are useful to run functions separately and side by side with the main functionality of the code.