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)

Audio Mixing Effects – Subtractive Synthesis and Phase Shifts

February 11, 2019

Reaper – Making Music

Audio Terms

Roland Blog – Guide To Subtractive Synthesis

This blog post has a very quick, basic description of a lot of subtractive audio creation methods. This covers waveforms: sine, sawtooth, square, and triangle; amplifiers with volume envelopes; and filters.

Making Music – Difference Between Phase, Flanger, and Chorus Effects

As the title describes, this covers the 3 effects: phase shifters, flangers, and chorus effects. They all deal with making duplicates of sounds but slightly offsetting them to create different effects.

Izotope – Understanding Chorus, Flangers, and Phasers in Audio Production

This is just more descriptive takes on the duplicating/phase shifting type effects. They also include examples where these effects are used in actual songs, as well as a lot of images to visualize how they work.

Reaper: Envelopes and Automation

February 8, 2019

Learning Reaper

Automation and Envelopes

Reaper – Envelopes and Automation

Continuing my learning with Reaper, I went through this tutorial to learn a bit about the envelopes and automation. These two things together basically allow you to vary the parameters of parts of the track at any time in anyway you want.

Each track has a “share” looking button that allows you to access the envelopes for that track. Here you can see all of the parameters available have options to create envelopes to automate, as well as any of the FX tied to this track. Making them visible shows them (either on a separate track or on the same track, which can be swapped). Arming them dictates which ones will be written over if you decide to write new automation.

There are also several automation modes:

  • Trim/Read: Plays automation with some editing capabilities
  • Read: just plays automation
  • Touch: records actions while doing something, then stops applying whatever you’re doing immediately on release
  • Latch: lets you record during play, but then continues to apply your last action when you let go
  • Write: records whatever you’re doing specifically, including nothing if you stop performing actions

You can also apply separate envelopes to the Takes, as opposed to the track. This lets you apply separate and different envelopes to an item that aren’t specifically tied to the track. This gives you multiple levels of control to affect the track.

You can also apply envelopes/automation to several tracks at once through master/slave connections. Use “Grouping”, and assign a track (i.e. the Master Track) as the master, and then choose the group which you want to apply to as the slaves. You will also want to select the parameters you wish to automate. Just creating an envelope for the master will NOT instantly apply to all the slaves. You need to set the master to a write mode, and it will record all the automation to the individual tracks. So you could technically use it to apply an envelope to multiple tracks, then delete the original master track and keep those additions.

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.

Grayboxing Levels in Unreal

February 5, 2019

Grayboxing in Unreal Engine

Basics of BSP

Wiki Unreal Engine – Basic Level Design BSP

I’ve started to learn the basics of the Unreal Engine (UE4), primarily with respect to it’s BSP (Binary Space Partitioning) and grayboxing levels. It’s the engine of choice for our Architectural Approaches to Level Design class specifically for this purpose.

Brushes

Unreal provides a base of shapes to work with that are perfect for setting up the overall shape and scale of a level or world in 3D. There are boxes, cones, stairs (linear, curved, and spiral), cylinders, and spheres. These shapes however also have various parameters associated with them that really help you mold out your world. The objects can have their sizes changed without strange scaling effects that need to be accounted for. The stairs have parameters for stair size and shape.

One particularly useful feature is that these shape brushes can be either additive or subtractive. Additive does what you would expect, creates the shape in the world. Subtractive however removes the colliding volume from any existing additive shape it intersects with. This can quickly and easily create some interesting shapes, or help build out rooms and doorways. Speaking of rooms, another helpful feature for this is that you can make some of these shape brushes hollow. This leaves a thin shell of the shape with a completely empty volume.

Geometry Mode

Finally, if you really want to stretch the creativity of your shapes, you can further edit them in Geometry Mode. This tool reminds me of Maya; it lets you do things like extrude faces or move around/remove vertices. This mode lets you craft the shapes almost anyway imaginable and is very easy to use.

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

Learning Reaper – First MIDI Song

February 2, 2019

Learning Reaper

First MIDI Song

Reaper – First MIDI Song Tutorial

This was my first experience using Reaper software, learning to create MIDI audio files. There were some bumps getting started but it worked pretty well after I got going.

The first issue was since I use a Windows laptop it was recommended I get the ASIO audio drivers for working in a digital audio workstation (DAW). I did get those installed ahead of time and it was easy to set them as my audio drivers for Reaper, but it caused some issues since I didn’t fully understand it (and still don’t completely).

Using the ASIO drivers in Reaper made it impossible for me to watch the tutorial videos, as those videos had issues when they went to use the audio driver then. From my understanding, the ASIO drivers specifically make it so one specific program has full control of the audio drivers to help it accomplish its goals, a major one of which is reducing latency. The big latency occurs between playing a virtual instrument and the audio output of it through the software. I eventually just had to use some other audio drivers to mess around with Reaper and listen to tutorials on the same device (and found out quickly how annoying even a small latency is when trying to keep a rhythm).

The Reaper interface also took me a while to get a hang of. Unfortunately my setup and docking did not end up working exactly like the tutorial, which I figured was some issue from just version differences, so that actually took a lot more time to get into a manageable spot than estimated. I was never able to get the Mixer docked “above” the MIDI keyboard section, but I was finally able to get the Mixer to show one mixer track at a time after hours of messing around (turned out I just needed to change a “right click in empty space” setting pertaining to holding the width of the mixers.

After getting through all the initial setup pains, everything actually went really well. Importing the different instrument tracks and messing with the settings and playing them is intuitive and well labeled. I really like how structured you can touch up the tracks after playing. That was especially helpful since I had the latency (messing up the rhythm), and I was using a computer keyboard to play (which makes playing the correct notes pretty difficult). Both of these things and WAY more can be edited after playing to make perfect whole, quarter, eight, whatever notes and play them at the exact right beats.

SUMMARY

  • ASIO drivers are weird and demand focus from a single software (can use workarounds but hard to setup)
  • Try to keep your digital instruments together folder wise, but if you need different ones, makes sure to add other locations in settings
  • Mixer – Uncheck “Show multiple rows of tracks if size permits” if you want your tracks to “stack”
  • Reaper is pretty easy to just mess around with (lots of drag and drop and just playing)
  • Make sure to keep instrument files in same place, or add them to locations Reaper searches

Concept for System for Generative Approach for Physics Based Games

January 31, 2019

Thesis – Generative System for Physics Based Games Concept

Text Book Problem Generator

My current thought on a system for developing generative processes for these games is somewhat like making a framework for problems in a physics text book. With the new system I’ve setup for directly tying physics concepts to these physics games (those lists of physics topics), I think I can relate a game’s parameters (those systematic game mechanic values) to the variables of the foundational equations corresponding to that same game’s potential learning concepts. Again, using Angry Birds as an example, let’s say “Impulse and Momentum” is a potential learning concept. A basic equation for momentum is (momentum) = (mass) * (velocity). Using this information, we can see that varying any parameters equivalent to or pertaining to the variables in this equation will require the player to “solve” the new “problem” presented to them by similarly varying their responses to the system.

So for example (an example within an example), varying the bird’s mass parameter directly correlates to varying the mass in the momentum equation. If the player is still trying to meet a similar/certain momentum result, they basically have to “solve” this equation by determining the correct velocity.

I know this might seem a bit obvious, but I’m hoping it’s one of those situations where it just works out so nicely because it’s actually a good solution. This system also presents a fairly basic way of ensuring different in-game scenarios feel differently. You could keep track of the values for the “problems” presented to the player, and just check if a produced “problem” has values that are “too close” to these archived values. Back to the Angry Bird example, a game scenario presented to the player that they needed momentum in the range of (10 kg*m/s – 15 kg*m/s) with a bird of mass 5 kg (so solution range velocity is (2 m/s – 3 m/s)). The next produced scenario is a momentum range of (11 kg * m/s – 16 kg * m/s) with a bird of mass 5 kg (solution range velocity is (2.2 m/s – 3.2 m/s); maybe the system throws this out and generates a new scenario because it sees the momentum range, mass, and solution velocity are all very similar to something produced before.

The needed “distance away” from an archived problem could also be a weighted, combined distance of all the variables that could be tweaked depending on how you want to setup the system. This way, maybe you have another problem with a similar solution value (like the (2 m/s – 3m/s)), but the momentum and mass involved in the scenario are so different that it still feels like a different, interesting experience.