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

More Thesis Physics Game Concepts

February 14, 2019

Thesis Physics Game Concepts

Prototypes

Angular Speed and Momentum

So far this prototype has a simple concept where the angular speed is kept constant, but the player can move the center point to change the center of rotation as well as the radius of rotation. This altering of the radius lets the player influence the local velocity of the object significantly. They can also change the direction of rotation.

  • Left Mouse Click: moves center of rotation
  • Space: changes direction of rotation


Magnetic Force with Rail Gun

This is a very basic replication of how a rail gun works with currents creating magnetic forces through the Lorentz Force. The player can alter the amount of current in the rails, as well as the rail length to change the distance the projectile is fired.

  • Q, W: Raise, Lower current in rails
  • E, R: Increase, Reduce length of rails
  • Space: Fires projectile
  • P: Resets game


Coulomb’s Law

This concept emulates the basic Coulomb’s Law, producing forces between charged particles. Opposite charged particles will attract, while same charged particles will repel. The player can also add horizontal force to move the object.

A game concept using this foundation might be that a player moves along a certain axis automatically, but this “track” has charges on each side that the player can either increase/decrease to influence the position of their charged particle within the track (horizontally).

  • Left/Right(A/D): Add left/right force to object


Buoyancy

This system focuses on emulating buoyancy forces. The main player object has mass and weight, so it only floats when the buoyancy force is greater than the gravitational force (otherwise the object will still sink, as seen when it hits the top liquid, butane). This system also uses Unity’s drag so the velocity of the object does not get out of control.

The game concept for this is the most fleshed out. This would go with a physics puzzle game where there are separated containers that initialize as empty. Before the player traverses through the level, they can see the level and attempt to fill the various containers with different liquids to travel through the level. Having different liquids will change your speed in that section, as well as what direction you are going (floating/sinking), so the player must set the level up in a way they can successfully navigate through various obstacles.

  • Left/Right (A/D): Move object left/right

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

Tower Defense Tutorial – Brackeys – Ep. 13

February 13, 2019

Tower Defense Tutorial

Episode 13 – Lives

Youtube – How to make a Tower Defense Game (E13 LIVES) – Unity Tutorial

By: Brackeys
Ep. 13

We started by adding another public int, Lives, to the playerstats script. We then copied the bottom in-game canvas and pasted it to the top to hold our lives UI text element.

This tutorial involves a lot of references between different scripts. They suggest that if you’re making a larger game with a lot of moving components that you want to optimize, make calls to methods within the other scripts that do the changes locally, as opposed to directly altering the variables from the other script. In this tutorial, they end up just having everything go through the GameManager and having it handle everything locally.

We created a GameManager script for the gameManager object. The first thing we have this doing is handling the game over situation. It checks if lives <= 0, and if so, runs the EndGame method. We also added the standard gameEnded bool just so the check doesn’t run the EndGame method many times.

We then looked at the enemy script to start fleshing out its functionality. We added a health int, as well as methods to deal with receiving damage, TakeDamage, and dying, Die. TakeDamage also receives an int as input to determine how much damage to apply.

Next was filling out the Bullet script. We updated the Damage method so it grabs the Enemy script component of what it hits now and calls the TakeDamage method we added. We also added a damage int to Bullet that we could pass into TakeDamage to control how much health Damage removes.

Finally, we created another particle effect for the death of the enemy objects. This was another simple one copied from our bullet impact effect, we just varied the values a bit and changed the material to that of the enemy to look like the enemy is breaking apart. I also noted some differences in the particle editor over the large difference in Unity versions.

LOCATIONS OF BASIC METHODS

This section will just list some of the small basic methods created, where they are placed, whether they are public/private/etc., and whether they take input variables to help keep track of a framework for creating really simple games.

      Enemy

    • Take Damage(int amount) – Public – Applies damage to the object based on the int input
    • Die() – Private – Performs basic functions when health reaches 0, like destroy gameObject
      Game Manager

    • End Game – Private – performs actions when end game state is reached (i.e. Lives are 0)
      Bullet

    • Damage(Transform enemy) – private – gets the Enemy script component of the transform entered and calls the TakeDamage method, sending with it the damage variable from Bullet

SUMMARY

  • Larger projects may work better by calling internal methods of separate scripts to handle variables locally instead of directly changing the variables from the outside script
  • Make small, separate methods to deal with “EndPaths”. Could look into this terminology more.
  • Unity’s particle creation system has definitely changed over time, so just be aware when doing older tutorials.

Tower Defense Tutorial – Brackeys – Ep. 12

February 12 2019

Tower Defense Tutorial

Episode 12 – User Interface

Youtube – How to make a Tower Defense Game (E12 USER INTERFACE) – Unity Tutorial

By: Brackeys
Ep. 12

We created another bool property in BuildManager called HasMoney, which checks if the playerstats has enough money to build what the player is trying to build. This was then used as a check to determine what color a node should be when the player hovers over it.

Next we moved on to creating UI. We moved the timer and money into a canvas in world space, below the main play area. There are weird interactions between UI element scaling and font size. They multiply together so you can get the same size by raising one and lowering the other, but even though the give the same multiplicative size, the resolution can be different.

We updated the wave spawner timer. We added a clamp to it so it never goes below 0. We also edited the formatting of the countdown timer text so that it showed 2 digits before the decimal point and 2 after (the hundredths place). This was done with string.Format(“{0:00.00}”, countdown).

We also added a script, MoneyUI, to the money UI element. This solely references the playerstats money variable and updates to that as text. This definitely does not need to be done in Update, and would be more efficient to happen when the money value changes only.

We added cost UI elements to the turret buttons. These were just simple panel and text UI elements, with the cost hard coded (hard typed) in. You could add functionality to tie this to their true values in script.

Finally we added some particle effects on building a turret. This started by creating an empty game object slightly raised vertically, then adding the particle system as a child to this. This was with the intention of rotating the parent empty object without moving the anchor of the particle system.

PROBLEMS

My UI elements were acting strange between the Horizontal Layout Group on the Canvas and the Layout Elements on the UI buttons (turret images). I was not getting the expected results with the preferred height and width of the Layout Elements (they would not change to those values even though they had room), but I could just manually change them just fine (so the horizontal layout group wasn’t restricting them from being those values). This is extra strange as there was an Editor note specifically stating “Some Values driven by HorizontalLayoutGroup”.

SUMMARY

  • Scaling UI Element to fit that around it: Under anchor presets, hold “Alt” and select the bottom right corner option
  • Font size multiplies with the UI element scaling, and you can get weird results sometimes. i.e. I had to change my UI scaling down from 1 to 0.1 because even though I could just use one tenth the font size to fit the same space, this gave the text poor resolution.
  • Use string.Format to determine number of decimal places to show in number strings. The amount before the decimal point appears to also be important. (i.e. We used 0:00.00, which indicated which element to have two digits before and after the decimal point)

Game Architecture with Scriptable Objects Talks

February 7, 2019

Talks on Scriptable Objects

Unite Talks – 2017

Youtube – Unite Austin 2017 – Game Architecture with Scriptable Objects

By: Ryan Hipple

Youtube – Unite ’17 Seoul – ScriptableObjects What they are and why to use them

By: Ian Dundore

Unite talks on using scriptable objects for your game architecture. This just seems like a good things to learn about to keep your game creation/coding organized and easy to work with. Scriptable objects are something I need to learn more about in general.

Thesis Game Concept – Buoyancy

February 6, 2019

Buoyancy Game Concept

Thesis Physics Game Concept

This concept focuses on creating a physics-based game with a lot of variable parameters using buoyancy to guide the main mechanics.

The first focus is just setting up a script that handles adding buoyancy force to an object. This script was named BuoyancyApplicator. It has a section of variables dedicated to determining the buoyancy force (all the variables in the basic buoyancy force equation), a section dedicated to different geometry dimensions (to determine volume for the previous equation), and then other Unity specific variables (such as RigidBody component). The standard buoyancy force equation used is:

(buoyancy force) = ((liquid density) * (acceleration due to gravity) * (volume of displaced liquid))

All of these are variables we can alter to provide a different experience, but for the simplest version in a given scenario, we can keep gravity constant, the volume displaced will be a constant (from the shape of the object) as it will be fully submerged the entire game, and liquid density just changes when the object goes from one liquid to another.

The game will involve the player controlling an object going through different liquids, so we needed a way to account for this transition. Since we just need to change it upon entering a new liquid, I placed the update for the liquid density variable in the OnTriggerEnter, and just have the “liquids” has trigger collider areas.

In an attempt to make it more physically accurate, I implemented Unity’s own rigidbody drag factor. Fluid drag is a fairly complex calculation, so in an attempt to just mimic it simply, I set the drag equal to liquid density times an arbitrarily defined drag coefficient that is manually assigned. I am not entirely sure how Unity’s rigid body drag works, but this approach seemed to give the desired result for the most part. It was especially helpful for cases where I had the object speed up a lot going through a very dense liquid, and then slowing down when entering a less dense liquid. All of this together even worked to have the object sink when it entered a very low density liquid.