Tower Defense Tutorial – Brackeys – Ep. 11

February 4, 2019

Tower Defense Tutorial

Episode 11 – Currency

Youtube – How to make a Tower Defense Game (E11 CURRENCY) – Unity Tutorial

By: Brackeys
Ep. 11

This episode gets into setting up the currency system for the game. We started by creating the TurretBluePrint script. This was set as System.Serializable, which lets us see the fields of the script in the editor. We also removed the MonoBehaviour reference (very important, I initially missed this and it was not showing up in the editor properly). We then went back through previous scripts (such as BuildManager and Node) and applied this new TurretBluePrint class where it made sense.

We finally moved the method that actually builds the turrets from the Node script into the BuildManager script. This started by creating a bool property CanBuild in the BuildManager. As a property, we only allow it to “get” something (it only has the get part of get/set). So it was:
Public bool CanBuild {get {return turretToBuild != null}}
Similar to writing a small function that checks if turretToBuild is equal to null or not.

We created a small helper method in the Node script simply titled GetBuildPosition. This returned a vector3 that summed the node’s transform.position and the determined positionOffset. This vector3 could then directly be referenced as the precise location to instantiate a turret relative to the node selected. Also wanted to make the GameObject turret variable in node public, so we added a Header “Optional” to make it very clear in the editor it was ok if this was not filled with something.

This is how everything works now:

  • Start by clicking on shop icon
  • Performs Shop method tied to button: calls SelectTurretToBuild method from BuildManager and sends it TurretBluePrint (class holding a turret prefab and a cost int) pertaining to the specific turret selected
  • In BuildManager, this method just sets the turretToBuild TurretBluePrint variable to the passed in TurretBluePrint
  • Then when player clicks on a node (OnMouseDown), it performs a few checks that just return first: is it over a UI element, if BuildManager’s CanBuild is false, or if turret does not equal null
  • If it passes all these checks, it calls the BuildTurretOn method from the BuildManager and passes in itself as the Node input for the method
  • BuildTurretOn instantiates the GameObject portion of the turretToBuild TurretBluePrint class (turretToBuild.prefab) at the proper position (from the node helper method GetBuildPosition)
  • Finally, BuildTurretOn also sets that node.turret variable to the instantiated turret gameObject (that node’s turret variable will no longer be null, so it will not pass the first OnMouseDown check)

Now we start on dealing with actual currency. We created a script PlayerStats to add to the GameManager to hold onto any player related stats. The most direct one being Money, which was created as a public static int so we could access it from anywhere easily. It will also carry over from one scene to the next. We then edited the BuildTurretOn method in the BuildManager so it would properly deal with currency. It first checks if the player has enough money before placing a turret (if they do not, then it does not do anything else). If that passes, it creates the turret and subtracts the cost from the player’s current money.

SUMMARY

  • *** Very Helpful! By removing the MonoBehaviour reference and adding the System.Serializable to a class, we can use it as a type of container to simply store multiple variables (different types and values) with multiple shown in the editor. For example, our TurretBluePrint class held a public GameObject and public int, so anytime we referenced a public TurretBluePrint in a script, it created a slot for a GameObject and an int in the editor tied to this one variable
  • Use Boolean properties (just “get” variables) as a safe and effective way to check state of other variables
  • Use small helper functions for cases of small arithmetic functions that will probably be needed a lot, especially if they can be well defined so the reason for the math is clear
  • Be careful with public static variables as they persist over scenes

Tower Defense Tutorial – Brackeys – Ep. 10

February 3, 2019

Tower Defense Tutorial

Episode 10 – Missile

Youtube – How to make a Tower Defense Game (E10 MISSILES) – Unity Tutorial

By: Brackeys
Ep. 10

This tutorial focused on the missile prefabs for the missile launcher object. There was a heavy focus on effects and visuals, but there were still some additional gameplay elements added to the Bullet scripts of the missiles specifically.

For the interesting gameplay of the missiles, a Physics.OverlapSphere was added so they could find other nearby gameObjects within a determined explosionRadius and damage those objects as well. This OverlapSphere puts all the colliders it finds into an array, which is then dealt with by a foreach loop.

We created a new particle effect for the missile. I still don’t quite understand the new nested prefab QoL changes in Unity, but I did create a nested prefab for this effect. The main effect was the debris falling apart, similar to the bullet. The child effect were flames, which were orange cubes that floated up. Finally we also added a point light that very quickly fades out. The fade out was done with the Animation window by recording and simply starting with the desired initial intensity, then reducing the intensity to 0 at a later time stamp.

SUMMARY

  • If you have a visual model that isn’t on the axes you want for any reason, just call it “Graphics” or “GFX”, and put it as a child to what you will consider the true gameObject to interact with and align that properly by rotating the new GFX/Graphics element
  • Look into particle effects, there are a lot of options
  • Look into nested prefabs in Unity 2018.3+
  • Physics.Overlap sphere is useful to find collidable gameObjects around a location

Tower Defense Tutorial – Brackeys – Ep. 09

January 29, 2019

Tower Defense Tutorial

Episode 09 – Missile Launcher

Youtube – How to make a Tower Defense Game (E09 MISSILE LAUNCHER) – Unity Tutorial

By: Brackeys
Ep. 09

This tutorial covers making the Missile Launcher turret. A lot of it is the same as setting up the first turret, but it’s good practice to repeat the setup. It is extra useful for me because I am using Unity 2018.3 and there is a new way of working with prefabs so any practice with that is very useful.

There is a keyboard shortcut for selecting a variable and changing its name across all instances within the script (and even other scripts). Use Ctrl + r + r, then just type the new name over the old one.

SUMMARY

  • VS Keyboard Shortcut: Ctrl + r + r : Lets you replace all instances of a variable (even across scripts) with a new name
  • Just keep practicing with new Unity prefab setup
  • Simple way of creating UI icon from last time worked well again here

Tower Defense Tutorial – Brackeys – Ep. 08

January 27, 2019

Tower Defense Tutorial

Episode 08 – Shop

Youtube – How to make a Tower Defense Game (E08 SHOP) – Unity Tutorial

By: Brackeys
Ep. 08

This tutorial begins to set up the shop UI for the tower defense game. Setting up the shop UI begins with adding a UI Panel to the Canvas. This was brought down to the bottom and set to stretch across horizontally with the anchors. Then a Horizontal Layout Group component was added, which helps deal with the organization/alignment of children UI objects within this UI object’s space. Those children UI objects are buttons, which are used to choose different turret options for purchase. Going along with the Horizontal Layout Group, all of the buttons had a Layout Element component added to them. This allows you to enter some information on things such as preferred dimension, min dimensions, etc.

We used a quick and simple method to create a nice visual “button” so the player knows what tower is being selected to build. We went into the existing turret model’s prefab and took a screen shot of it with the Snip tool. Then we took that over to Photoshop and erased out the background (this was more easily done by making sure to turn off the skybox in the prefab editor visual so the background was entirely the single Unity blue color). I also changed the PS canvas size to a nice 256 x 256 pixels. Then exported out a .PNG with transparency on. We pulled the image into the Unity editor and changed the texture to a 2D sprite. This image could then be used as the UI sprite of the button, and we had a button that is a sample image of the actual model of our turret.

A Shop script was added to the Shop gameObject. This mostly deals with the actions that the buttons on the UI should perform. This deals a lot with relaying information to the BuildManager script, so a reference to that is immediately set in the Start of the Shop script. It then has methods dictating what turret the BuildManager should be preparing to build. Then, as seen in the earlier tutorials, the Nodes (spaces to place turrets) have their own scripts to access the BuildManager to see what is prepared to be built, and then the Node script actually instantiates the turret as long as the proper conditions are met. The BuildManager acts as the central scripting “hub” for dealing with all of the turret building.

As a final QoL touch for the game, a restriction was placed for highlighting and selecting nodes that were behind important interactive UI elements (we don’t want players placing turrets when they are simply going to select a turret to build). To do this, we went into the Node script and added the namespace {using UnityEngine.EventSystems;}. Then in both the OnMouseDown and OnMouseEnter methods, we added an if statement that just returns {if (EventSystem.current.IsPointerOverGameObject())}. This stops the rest of the method from occurring if the mouse cursor is already on an EventSystems object (i.e. a UI element).

SUMMARY

  • Use Horizontal Group Layout and Layout Elements components on UI elements to help organize and space them nicely
  • Create simple UI button sprite images of models with Snip of prefab editor image, Photoshop out background color, export as .PNG with transparency
  • Have a script that deals with the UI element methods (i.e. what the buttons do) and have it reference the script(s) where most of the “work” is done
  • Use an if statement check with UnityEngine.EventSystems to make sure players clicking on UI elements don’t click on other game elements with that same click, using IsPointerOverGameObject

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

Field of View Tutorial with Mask Shaders

January 22, 2019

Field of View

Tutorial – E03

Youtube -Field of view visualisation (E03)

By: Sebastian Lague

This tutorial ties the Field of View (FoV) series in with shaders. These shaders block everything from rendering except what is viewed by the player character. The shader scripts actually had barely anything added to them, and I’m not completely sure what they did.

The shaders were both Standard Surface Shaders. A Stencil method was added into the SubShader section of both. In StencilMask, this method was just:
Ref1
Pass replace
In StencilObject, it was:
Ref 1
Comp equal
The only other additional code was in StencilMask, which was adding “Queue” = “Geometry-100” to the Tags, then ColorMask 0, and ZWrite off.

SHADER PROGRAMMING TERMS

  • ”Queue” = “Geometry-100”

    So these tags are terms that represent integer values that determine what is rendered first. Geometry has an integer value of 2000, and is the base for most opaque objects, so choosing “Geometry-100” will make whatever this shader is applied to render before anything labeled as just Geometry (like most opaque objects) as it will now have a value of 1900.

  • ColorMask 0

    ColorMask sets color channel writing mask. Writing ColorMask 0 turns off rendering to all color channels. Not sure exactly what this ends up doing.

  • Stencil

    The Stencil Buffer is a general purpose per pixel mask for saving or discarding pixels.

  • Ref 1

    This is the value each pixel is compared against and/or value to be written to the buffer.

  • Comp equal

    Comp compares the reference value to the current contents of the buffer.

  • Pass replace

    A Pass block renders geometry of a GameObject once. This determines what to do with the contents of the buffer if the stencil test passes (which might go with the Ref). Replace writes the value into the buffer.

ATTEMPTED SUMMARY

StencilObject is placed on the materials to all of the GameObjects, like the obstacles, the ground and the targets. This makes them render completely black. Then the StencilMask is applied to the ViewVisualization material of the player’s vision, and this “uncovers” the objects in vision by allowing them to render normally (removing the internal mask the objects are placing on themselves).

StencilObject creates a reference value of 1, then compares to that value. So it should only render pixels whose value equals 1, the reference value in the buffer. StencilMask has a Pass replace command, so this apparently writes the Ref value directly to the buffer. So this is writing the value 1 to the buffer. For some reason, this renders just before standard Geometry queue objects, and there is a ColorMask 0. This will require more shader knowledge in the future for me to understand fully.

PROBLEMS

For some reason, my ground plane was fading out on the edges. The outter edges would actually fade so much they completely blended into the background as the exact same color. I know the ground was still there as I could see it in the editor and the player did not fall when walking on the invisible ground area, but it just did not appear. Changing the Directional Light color to black fixed this for some reason, so there appears to be some strange interactions with these shaders and the lighting in the scene.

List of Tower Defense Tutorials for Unity

January 21. 2019

List of Tower Defense Tutorials for Unity

How to make a Tower Defense Game (E01) – Unity Tutorial

By: Brackeys

This is the start of a 28 episode series for creating a tower defense game from scratch. It is mostly 3D, although the game plays in a 2D environment.

0.0 Unity Tower defense tutorial – Introduction

By: inScope Studios

This is a 2D sprite tower defense game that uses tiles/grids to create its levels and environment. It also includes a lot of nice smaller tutorials along the way like creating a loading screen, some options screen elements, hovering for information boxes, etc.

1 Hour Programming: A Tower Defense game in Unity 3d [Tutorial]

By: quill18creates

This is a quick “speed run” of creating a basic tower defense game just to see if the creator could get one up and running in about an hour. This may not have the best practices, but can be good for finding some of the bare minimum requirements for getting a tower defense game off of the ground.

Learning Foundations of Unity Shaders

January 18, 2019

Intro to Shaders in Unity

Glitchy Man Material

Unity3D – Live Training Session: Writing Your First Shader In Unity

This tutorial was pulled from the tutorial list I created January, 17th (“Assorted Unity Tutorials – Structs, Shaders, and Unity Architecture”). IT not only introduced me to the core components that make up a shader in Unity, it also covered a lot of terminology and behind the scenes information to give me a better foundational understanding of how shaders operate.

Types of shaders you can create in Unity:
  • Surface Shaders: code generation approach that’s easier to write lit shaders than using low level vertexe/pixel shader programs
  • Unlit Shaders: don’t interact with Unity lights, useful for special effects
  • Image Effect Shaders: typically postprocessing effect that reads source image, does calculations, and renders result
  • Compute Shaders: programs run on graphics card, outside normal rendering pipeline; used for massively parallel GPGPU algorithms or accelerate parts of games rendering
Explaining Basic Shader Script

Shaders go onto a material. Determines how a material is rendered. Standard for Unity shader uses Shader Language. The Properties block is similar to public variables in Unity, as they can be seen in editor. The Pass block is where script passes logic to renderer. Tags explain how it wants to be rendered. The two structs (data functions) pass into main functions. These are the vertex function (vert) and the fragment function (frag).

Core Terminology for Shader Scripts
  • Vertex Function: takes shape of model and potentially modifies it; gets the vertices of model ready to be rendered; converts form object space to clip space (relative to camera); result goes to fragment function
  • Fragment Function: applies color to shape output by vertex function; this paints in the pixels
  • Property Data: colors, textures, values set by user in inspector
  • LOD (Level of Detail): this goes with how detailed object is (usually associated with idea in games where closer objects have higher detail and far objects have low detail)

Shaders do not use inheritance. Most classes in Unity start as Monobehavior, which gives you a lot of nice base functions. Shaders need that included, which is what the line { #include “UnityCG.cginc”} is for. This includes the use of a bunch of helpful helper functions.

Two important structs: appdata and v2f. appdata passes in information of vertices of 3D model. These are passed in in a packed array (variable with 4 floating point numbers: x, y, z, w). POSITION is a semantic binding, this tells shader how something will be used in rendering. V2f is short for “vert to frag”.

Coordinate system translations:

Local space -> World Space -> View Space -> Clip Space -> Screen Space

Looking into fragment sections

Fixed4 can either be: x,y,z,w or for color, r,g,b,a. Created a variable _TintColor in properties, which showed up in Unity inspector under the Unlit_Hologram material. This then needed to be used in the CGPROGRAM to actually do anything. We added this color to the fixed4 col found in fixed4 frag, which “adds” the colors together.

Making a transparent Shader

First, changed RenderType in Tags from Opaque to Transparent. Also needed to add “Queue” = “Transparent” here, as the order things are rendered is also important. Because of this, you want other things rendered before rendering the transparent thing because you want the transparent thing rendered “on top”. There are several primary queue tags that exist for rendering order. The following is the order of rendering generally, from first to last.

Primary Queue Tags for Render Order:
  • Background (first, back)
  • Geometry (Default)
  • AlphaTest
  • Transparent
  • Overlay (last, top)

Add ZWrite Off keyword. Tells us to not render on the depth buffer. This is usually done for non-solid objects (i.e. Semi-Transparent).

Displacing vertices and clipping pixels

Using the function “clip” in frag function to clip out pixels within a certain threshold. Adding sin function along with several variables (Speed, Amplitude, Distance, Amount (Multiplicative Factor)) into vertex function to move vertices around in object space, relative to the object. This is done before passing into the frag function. _Amount was a factor in a range between 0 and 1 just to control how much the shader effect was happening. The amount was important for the C# script used to control the effect on a time based interval. The C# script, HoloManGlitcher, could access the variables within the shader script. This was done simply through the material. (i.e. holoRenderer.material.SetFloat (“_Amount”, 1f); )

Field of View Tutorial E02 – FoV Mesh – by Sebastian Lague

January 16, 2019

Field of View

Tutorial – E02

Youtube -Field of view visualisation (E02)

By: Sebastian Lague

This is the second part of a tutorial creating a field of view (FoV) for a character in Unity. This focuses on an in-game visualization of the field of view that fills the entire viewing area. FoV visualization is a generated mesh. This will be built from tris made up by the character’s position and the end point of each ray cast within the FoV.

A struct was created to hold all of the information for the raycasts. Used transform.InverseTransformPoint to convert a point (Vector3) from a global value to a local value.

The FoV mesh initially had an issue dealing with the corners/edges of obstacles. A high resolution was needed (many rays cast) to reduce the visual jitter effect around obstacle corner/edges. This was addressed further in the tutorial. To solve this, approached the problem by determining when rays go from hitting obstacle to missing obstacle, and label these “min” and “max” values. We know edge must be between these two rays somewhere. Then you cast rays directly in between these two rays until you find the edge/corner (or somewhere very close).

This solution helped the case of the FoV mesh hitting an obstacle very well, but still had issues if the two sequential view rays hit two different objects. This case has both rays hitting an object, so the logic determines this case is fine, however it produces a similar problem to what we had before. To fix this, a distance threshold between the two ray hit locations was added. This assumes two points hitting far apart were most likely parts of two different obstacles. The solution appeared to make the FoV mesh much smoother.

PROBLEMS

My FoV mesh was glitching out sometimes when interacting with obstacles. Some of the points of the mesh were jumping to very far away and incorrect positions. This did not appear to happen at all in the tutorial video, but happens pretty frequently with my setup so it may just be a typing error within the code somewhere. I will have to investigate to determine the issue.

SOLVED

The tutorial provides the scripts through github, so I was able to compare them side by side and find the error. It was a typo. In the DrawFieldOfView method, in the check to see if the sequential raycasts hit the same type of thing where they are checking for the edge cases, they add either pointA or pointB to the viewPoints list depending on which one is not equal to zero. I had both of these cases adding pointA specifically, which is what was causing the very strange mesh shapes sometimes for cases where my Fow was hitting obstacles.