Tower Defense Tutorial – Brackeys – Ep. 21

February 28, 2019

Tower Defense Tutorial

Episode 21 – Pause Menu

Youtube – How to make a Tower Defense Game (E21 PAUSE MENU) – Unity Tutorial

By: Brackeys
Ep. 21

This tutorial focused on creating the Pause Menu.

To start, we create another UI Panel as the base for the pause menu, and added buttons for: Continue, Retry and Menu. This also had text saying “Paused”.

We created a new script on our Game Manager, PauseMenu. This would deal with the functionality of activating/deactivating our pause menu UI elements. This was done with a method called Toggle, which used a command of ui.SetActive(!ui.activeSelf) which would set whether it was enabled or not to the opposite of what it currently is.

We then got to actually pausing the game. This can be done by simply setting Time.timeScale = 0f. It is commonly mistaken that you also need to set Time.fixedDeltaTime to 0 as well, but this is actually taken care of by Time.timeScale already. We also need to unpause, so we set Time.timeScale back to 1f when that is needed.

It is important to note that while Time.timeScale is at 0, this does prevent some things from working. The hover color of UI buttons was still fine as it is not affected by the timescale, but animations you are running with the Animator will be. They need a specific setting changed in order to function properly. This was shown by trying to fade in our pause menu. Initially, we created a simple recorded animation of changing the alpha from 0 to 1, but when we ran it in game it did not appear. That is because the animation was frozen with the timeScale.

To prevent the animation from being affected by our timescale variation, we change the “Update Mode” in the Animator component of the object we are animating from Normal to Unscaled Time.

Then, we also wanted to animate the buttons some (instead of just having a simple highlight color). To start, we went to the Button (script) component and changed the Transition to Animation. We then selected AutoGenerate Animation. This gave us 4 options in the Animation tab for: Normal, Highlighted, Pressed, Disabled. These are the 4 states of the button. These let you set an animation to start whenever these separate events occur.

SUMMARY

  • Use [gameObject].SetActive(![gameObject].activeSelf) to inverse the current enabled state of a gameObject
  • Use Time.timeScale = 0f; to do a simple pause of your game. This should also set Time.fixedDeltaTime to 0f behind the scenes so you do not need to set this as well. (To unpause, set Time.timeScale back to 1f.)
  • If you want to animate objects during timescale = 0 (like pause menu animations), make sure to change their Animator component Update Modes from Normal to Unscaled Time.
  • To animate UI buttons, select Animation for Transition under the Button (script) component (built into Unity UI buttons). Can then select AutoGenerate animation to record animations like anything else, and for all 4 different states of the button (Normal, Highlighted, Pressed, Disabled).

Particle Systems and the VFX Graph in Unity

February 27, 2019

Particle Systems in Unity 2018 and Later

Particle Systems and New VFX Graphs

I originally intended to look up new tutorials for particle systems in Unity to get a better grasp of the differences in the newest version of the Particle System editor. This was because a lot of older tutorials had the old setup so some of the differences made it hard to follow. While I did find one newer particle system tutorial using the editor, I stumbled upon the Visual Effects graph which appears to be a node/graph based editor for creating VFX new to the latest version of Unity, so I gathered a lot of tutorials for that. Several of them are from Brackeys as well, which is someone I follow often for basic Unity tutorials.


Youtube – Everything to know about the PARTICLE SYSTEM

By: Brackeys

This is the video just going over a lot of the basics of the Particle System editor. Since this was only about a year old I hoped it would cover some of the weird differences I run into, like shaders for particle materials.


Youtube – Visual Effect Graph – Realtime visual effects In Unity 2018.3

By: Unity

This is a quick video from Unity that just shows off some of the basics and capabilities of the VFX graph.


Youtube – FIRE AND SMOKE with Unity VFX Graph!

By: Brackeys

This is a nice example tutorial by Brackeys on using the VFX graph to create a fire/smoke effect.


Youtube – MILLIONS OF PARTICLES! – Unity VFX Graph

By: Brackeys

This is another Brackeys tutorial using the VFX graph that just focuses on doing weird effects with a very large amount of particles.


Youtube – MAKING VISUAL EFFECTS IN UNITY 2018.3 | Beginner’s Guide: VFX Graph

By: Sykoo

This is a longer look into the VFX graph and a lot of it’s capabilities from the very beginning.


Tower Defense Tutorial – Brackeys – Ep. 20

February 24, 2019

Tower Defense Tutorial

Episode 20 – Sell

Youtube – How to make a Tower Defense Game (E20 SELL) – Unity Tutorial

By: Brackeys
Ep. 20

This tutorial focuses on implementing the “sell” functionality to go along with the sell UI button we have. We are also going to setup an upgraded version of the missile launcher and the laser beamer turret.

The upgraded versions of the missile launcher and laser beamer turret were just upscaled versions with some buffed stats and different material colors. These were set in the Shop TurretBluePrint editor sections as well.

For the selling function, we wanted to add that to our Node script. However, since we just wanted to code something standard to create the sell value of a turret, we ended up going to the TurretBluePrint to create this calculated sell value. This was done because we can now just reference the TurretBluePrint class anytime we want the sell amount, and if we ever want to change how that is calculated, we can just change it in one place instead of looking around for everywhere it is used. In TurretBluePrint class, we simply added a method, GetSellAmount, that returns an int that is just the cost divided by 2 for now. This method can now be referenced in the Node script to get that sell value.

The UI system is very easy to add functionality to. The main UI object holds the central script that keeps track of what we have selected and call methods on that node specifically, as well as containing all the basic UI methods (such as on click events). It’s very easy to know that anything dealing with altering a node goes through this script. It also keeps a lot of our UI functionality organized in one location.

SUMMARY

  • If you are using a variable multiple times that needs calculated, but may want to alter this calculation throughout the design process, it is good to have this done in one location as a small helper method and then reference this method when you want that value. That way you only have to change the calculations in one place to change them globally.

Tower Defense Tutorial – Brackeys – Ep. 19

February 23, 2019

Tower Defense Tutorial

Episode 19 – Upgrade

Youtube – How to make a Tower Defense Game (E19 UPGRADE) – Unity Tutorial

By: Brackeys
Ep. 19

This tutorial goes over upgrading our turrets after selecting them.

We started by moving the BuildTurretOn method from the BuildManager script to the Node script, and renamed it BuildTurret (since it will be obvious it is “on” that node now anyway). This was done because BuildTurretOn was making a lot of references to the Node script anyway, so it made more sense to just handle everything locally to reduce the number of references needed.

Next we created the UpgradeTurret method. This was mostly a copy/paste of our BuildTurret method, with a few tweaks (having a separate cost, possibly a separate effect). The biggest difference was that we couldn’t just instantiate the upgraded turret since we already have one there; we need to remove the initial turret first.

We created a new prefab for the upgraded version of our standard turret. We duplicated the original, scaled that up some, and changed one of the material colors just to make it clear it was a different version. I liked the way they organized this in the Asset hierarchy. Our folder structure was already: Imports -> Models -> [Model Name]. We further branched this into two separate folders to hold the materials for the standard turret and a folder for the materials of the upgraded turret.

We edited the NodeUI so that the upgrade cost is tied to the currently selected turret’s TurretBluePrint now. This makes sure the upgrade cost updates according to which type of turret is selected.

Finally, we created the case for when the turret has no more upgrades available. In the NodeUI script, we check the upgrade state (currently just isUpgraded) on the turret. If it is not in the final state, perform normal upgrade functions, if it is, set the text to something like “Done” or “Maxed Out”, and set the upgrade button itself it be non-interactible (upgradeButton.interactable = false).

SUMMARY

  • If a method makes a lot of references to another script/class, it might make more sense to just move that method into the script/class
  • They use an underscore ( _ ) before a variable to indicate it is just a local variable field version of a variable (i.e. _turret instead of turret since _turret is created and used specifically within a single, smaller method)
  • If you have upgraded versions of models that are mostly varying the materials, create separate Material folders for each variation to keep organized
  • Use buttonName.interactible = false to stop button from having hovering animations or performing actions when pressed

Tower Defense Tutorial – Brackeys – Ep. 18

February 18, 2019

Tower Defense Tutorial

Episode 18 – Selection

Youtube – How to make a Tower Defense Game (E18 SELECTION) – Unity Tutorial

By: Brackeys
Ep. 18

This tutorial focuses on creating “Selection” functionality, allowing the player to select a turret.

We started by adding World Space UI to an example turret prefab. This will provide us with “sell” and “upgrade” functions later. For now, we just need to set these things up so they will appear when a turret is selected. This involved more use of the Horizontal Layout Group component on UI objects, which consistently do not give me the same result as the tutorial, so I’ll need to look into those.

After setting up the UI, we got into the script for implementing the UI. We started by cleaning up the build manager so that the game doesn’t get cluttered in the situation where it tries to build turrets but also selects a turret on a node. We simply added a “SelectNode” method to the Buildmanager that sets a node variable to the selected node, but also sets turretToBuild to null. Likewise, we added a selectedNode = null; call in the SelectTurretToBuild method. This helps ensure we’re only doing one at a time in game.

We are actually just using this one UI object and moving it around and turning it on/off. Initially we created a new script, NodeUI, and placed that on this node UI system of objects, and gave it a simple method where it would move its position to the target.GetBuildPosition(). This was used instead of target.transform.position because that would give us the center of the node’s location, where as this gives us some other variation of the position that is more applicable (look into).

We also wanted to add some extra functionality, including turning off the UI if the player selects the turret again. This was as simple as checking if the selectedNode was in fact the node clicked on (again). This would then deselect the node, with the Deselect method, which just set selectedNode to null and disabled the nodeUI canvas.

SUMMARY

  • Horizontal Layout Group does not work for me like it does in the tutorials. It may have been changed over Unity versions so I need to look into this.
  • On a Canvas UI object, you can change the values of “Dynamic Pixels per Unit” and “Reference Pixels per Unit” in the Canvas Scalar component to make UI elements show up better depending on the scale you’re working at
  • What does GetBuildPosition() do exactly?

Tower Defense Tutorial – Brackeys – Ep. 17

February 17, 2019

Tower Defense Tutorial

Episode 17 – Game Over

Youtube – How to make a Tower Defense Game (E17 GAME OVER) – Unity Tutorial

By: Brackeys
Ep. 17

This tutorial deals with creating the Game Over screen as a series of UI elements.

We started by adding a gameObject to our OveralyCanvas titled GameOver. This gameobject will hold all of the UI elements dealing with the game over state: new panel, text objects, and buttons for retry and menu.

We changed the OverlayCanvas scaling to “Scale with Screen Size” and used the slider to dictate that it would go by the height of the screen to scale our overlay UI canvas.

For scripting the game over scenario, we decided to expose the gameEnded bool variable to make it easier for everything to know when the game was over. This is useful for basic things such as disabling game inputs on the game over screen. We exposed it by making it a public static bool (and also renaming it to GameIsOver).

Making GameIsOver a public static variable however means it carries over from scene to scene, retaining its value, so we need a way to reset this value. This is easily solved by setting the value of GameIsOver to false in the Start method of our GameManager, as the Start method is called every time a scene begins.

To better organize our objects and scripts, the GameOver game object containing all the game over UI objects also holds the GameOver script. This script will handle everything during the GameOver phase of the game. This works by having the entire GameOver object disabled, and then the GameManager enables it when the GameOver state is reached. At this point, the GameOver object has an OnEnable method in its script, which acts like Start, but occurs when the object is enabled. This begins all the processes needed to be handled during the GameOver phase.

Finally, we wanted to add some animations to our game over screen. We used a basic approach to fading the UI objects in, with some minimal movement and scaling of text/buttons. There was a suggested easy way to fade in UI objects. If you add a “Canvas Group” component to a UI element, it has an alpha value directly tied to it that effects that entire object. This makes it very easy to fade objects in/out by just varying this value from 0 – 1.

SUMMARY

  • Have your GameIsOver as a static bool to make it easier for every script to access this to basically shut down during the game over state
  • Group your Game Over scripting into a single objects that starts OnEnable to keep things organized with minimal references needed
  • Use Canvas Group components on UI elements to easily change entire alpha value (good for fade animations)
  • Offsetting your UI animations can make the screen feel more organic/less robotic

Tower Defense Tutorial – Brackeys – Ep. 16

February 16, 2019

Tower Defense Tutorial

Episode 16 – Slowing

Youtube – How to make a Tower Defense Game (E16 SLOWING) – Unity Tutorial

By: Brackeys
Ep. 16

This tutorial will clean up some of the Turret coding, as well as add a slowing effect to the Laser Beamer turret, as well as damage over time (DoT).

We added this line of code to apply the damage over time to enemies:

targetEnemy.TakeDamage(damageOverTime * Time.deltaTime);

This initially held the GetComponent() call to get the Enemy script component of the target, but this would be very expensive to do every frame. To remedy this, we created the targetEnemy variable which is assigned the GetComponent() value when we select a new target, so it only needs done once each time the laser starts hitting a target.

To clean up our Enemy script coding, we separated it out into two scripts: Enemy and Enemy Movement. Brackeys suggests it is a good practice to keep all of your enemy’s stats or values that you want to change about them in one script, and have the other script components reach out to that information when they need those values (i.e. speed, health, etc.).

To connect our new EnemyMovement script to the original Enemy script, we simply added an Enemy variable, enemy, and then GetComponent() on that at start. To further ensure they are connected (i.e. Future editors know to keep these together), we added a RequireComponent(typeof(Enemy)) above the class name.

We wanted the laser to slow the object a consistent amount. We did not want slows to stack from multiple lasers or increase over time in any way. This resulted in creating a startSpeed to go along with speed. Speed was set equal to startSpeed in the Start method of Enemy. This allows us to constantly set speed as a fraction of startSpeed, since startSpeed is never modified. This also meant we didn’t want to show speed in the inspector, but still needed to keep it public, so we added [HideInInspector] above it so it did not show.

This worked well to slow the enemy, but then it remained slow forever. We needed to reset the speed somehow. Their solution was to just reset the speed every frame in the Update that was moving the enemy (after the movement occurred). While this works, this seems like a lot of extra calculations that could be solved in a cleaner way.

Suggested cleaner solution to slow and movement being off by a frame: Have a list of debuffs that the enemy script goes through each frame to check what debuffs are currently on it, and then apply those to any actions it does.

In this case, we actually went into the Script Execution Order (Project Settings -> Script Execution Order). This allows you to drag in scripts to dictate what order they are processed in. The number value entered is the number of milliseconds between this script and the default time.

SUMMARY

  • Simplest way to do damage over time is to have a method dealing damage * time.deltaTime that is called in Update somehow
  • RequireComponent makes sure that any time you add this script to an object, it will also add the specified component as well. Good for making sure all the components needed for a certain script to reference are on a given object.
  • It is good practice to keep all of an object’s “stats” in one place, and have other functionality that references these stats separated out into other components/scripts. (i.e. Our enemy stats were kept in Enemy, but another script, EnemyMovement, was created which referenced Enemy for stats like speed and then applied that to all the functionality internally)
  • Use [HideInInspector] if you want a public variable but don’t want it shown in the inspector
  • You can use the Script Execution Order to dictate what order scripts are run

Tower Defense Tutorial – Brackeys – Ep. 15

February 15, 2019

Tower Defense Tutorial

Episode 15 – Laser Beamer

Youtube – How to make a Tower Defense Game (E15 LASER EFFECTS) – Unity Tutorial

By: Brackeys
Ep. 15

This tutorial will focus on creating extra effects for our laser. We’re adding a LaserImpact particle system, starting as a duplicate of the BulletImpact particles.

We started by making it a new material, LaserImpact material, and making this green with some emission. As many other particle effect parameters, this is setup differently in newer versions of unity. The intensity is in the color selector palette after turning on “Emission” for the material. Since we have so many particle systems now, we’re narrowing down what they collide with. We put all the nodes and ground planes on an “Environment” layer and made sure the particle system only collided with that.

Instead of making this particle effect its own prefab like the others, we attached it as a child to the Laser Beamer object. This would then just be an object we enable/disable when needed. For the particle system, we actually use Play() and Stop(), instead of enable/disable. This makes sure you aren’t creating multiple instances of the particle effect, and also makes it so that when you turn off the particle system, it doesn’t immediately go away. The residual particles will still do their thing.

To position the particle system, we just started by making its position that of the target. This however puts it directly in the middle of the target, where we would prefer having it on the surface where the object is hit. To do this, we created a vector that is the difference between our turret’s firepoint and the target to get the direction. Then we rotated the particle system to match this direction, and added/subtracted a small amount from the target position to place it slightly closer to our turret (so hopefully closer to the surface of the object). There might be a cleaner and more consistent way to do this with rays.

We wanted to add more effects to this laser, so we added a child particle system to this original laser ImpactEffect. Play()/Stop() will also apply to any children particle systems of an object. The material they used for this wanted to use the shader Particles -> Additive, which is only a Legacy option now. The new Particles -> Standard Surface shader has a rendering mode blending option that has an additive option, so I tried to see if that was similar. It seemed to give a similar effect, as long as I put the material (we were using the default particle material) in the Albedo map.

We gave the particle a blinking effect by editing the “Color Over Lifetime” to have 0 alpha at the end. So as it would loop, it basically faded in and out very quickly. Finally we added a green light to this particle system as an extra glowing effect. This however, would leave the light at its last position when an object got out of range.

When we went to fix the light (enable/disable it), they mention we could use animations instead to control all of these particle system events as opposed to scripting all of them. The light was just another reference in the Turret script that we enabled/disabled with all the other laser effects.

SUMMARY

  • I really need to look into tutorials for the new particle system editor to help find equivalent options for these older tutorials
  • Use Play(), Stop() with particle effects instead of enable = true or false for normal use
  • Create blinking effect in particle system with looping, short lifetime, and setting “Color over lifetime” final alpha value to 0

Tower Defense Tutorial – Brackeys – Ep. 14

February 13, 2019

Tower Defense Tutorial

Episode 14 – Laser Beamer

Youtube – How to make a Tower Defense Game (E14 LASER BEAMER) – Unity Tutorial

By: Brackeys
Ep. 14

This tutorial creates the Laser Beamer, yes beamer, object prefab. Something I’ve done when importing these to make it more similar to the tutorial, under the Materials tab for this imported model, I use “Extract Materials” to make sure all of the materials become easily available to alter and move around in the Unity editor. Before making it into a prefab, we did the same steps we did with the other turrets: add partToRotate empty object, add firePoint empty object, child turret head and firepoint to partToRotate empty so they rotate properly/easily with a forward facing z-axis object.

Everything else was also updated similarly to the other turrets. We added another TurretBluePrint public class to the Shop script so we can inform it of the new prefab to use for the LaserBeamer and its cost. We then added the LaserBeamer shop button (sprite image on UI) and added its new click event for selecting the LaserBeamer.

The laser beamer is different in that its projectile will use a Line Renderer component to simulate a laster. This has clearly received a lot of updates over the several iterations of Unity between now and this tutorial. The “Positions” section has more of a table setup. The “Width” parameter section is now actually a small line graph instead of just values (assuming this allows for more variation with curves, etc.).

The line renderer material gave me some issues, which I cover in PROBLEMS below. However, it seems the material I chose doesn’t allow for variation of the alpha value in the line renderer color component. Another difference here is the suggested shader for the line renderer material was “Particles – Alpha Blended”, which no longer exists. I used “Particles – Standard Unlit” which worked for me. The colors are also different now. Instead of just a start and end color option, it is now a full gradient preview bar with colors on the bottom and alpha values on the top.

Then we edited the Turret script to deal with this new type of weapon. We separated out the variable headers from Attributes into General, Use Bullets (default), and Use Laser to keep everything organized. Then we moved on to dealing with the line renderer in a method, Laser.

We started scripting the line renderer by setting its positions (values in its position array that determine the points to connect with a line). Since we only have two points, those are the start and end point of our line. It’s as easy as:

lineRenderer.SetPosition(0, firePoint.position);
lineRenderer.SetPosition(1, target.position);

Where the first input in SetPosition is the element number in the position array of the line renderer, and the second input is what that position is. So this example draws a line between our firePoint (shooting location) and whatever the target is.

Our laser worked, but it would stay in its last position if the target moved out of range (since it no longer needed to update its location). Since we already had a return happening for the check when there is no target, we just added a laser specific check to also enable = false for the line renderer when there is no target.

PROBLEM

SOLVED: My line renderer was not displaying properly after applying a basic material to it in the prefab editor (it was just solid black, when the material was white). At first I thought this was a lighting issue in the new prefab editor, so I found out that you can create a scene to use as the prefab editor scene and add it in your Project Settings. So I did that and it was still black, but I noticed if I rotate around it was white for about 180 degrees of viewing rotation. I then noticed the next part of the tutorial mentioned changing the shader for the material, and this directly solved the issue. Line renderers might deal with materials strangely, and may often use non-default shaders.

BONUS OBJECTIVES

Add particle effect to the end of the laser line renderer for that sparking impact effect a lot of lasers have.

To set up the Turret variables/editor even better, have a variable called UseBullets, or an enumerator to select either Bullets or Laser, then show fields depending on what you selected. Create an editor script for this. Look up “Unity Custom Editor”.

SUMMARY

  • When importing models, use “Extract Materials” to specifically pull out all of the materials to make them easier to edit.
  • Check the shader for the material you apply to line renderers since they seem to act uniquely
  • Look into “Unity Custom Editor” to learn about editor scripts