Wwise Integration with Unity

March 10, 2019

Using Wwise with Unity

Game Audio

Youtube – Wwise and Unity: Getting Started with Unity & Wwise, Part 1
Youtube – Wwise and Unity: Ambient Sound Sources, Part 2

By: WestSideElectronicMusic

Wwise is a powerful audio editing tool specifically molded towards producing game audio. It also has strong integration with the Unity game engine that makes working between the two much smoother.

These tutorials help show the basic integration steps to make sure the two softwares can communicate with each other, and then starts to get into the basics of using WWise to produce interesting audio for your games. Between the two of them, we covered adding in a simple footstep sound effect and a torch sound effect.

The footstep audio was done to show the minimum required to add audio into Unity through Wwise. It was mostly important to note the need for creating audio effects in Soundbank objects in Wwise, then generating the objects to import into the Wwise editor in Unity. These objects then need to be placed in the Unity scene to actually be accessible as audio clips. The footstep effect will also be built upon in later tutorials to add some randomization as well as modifying the audio for stepping on different terrains.

The torch example got into some stronger features of WWise, focusing on 3D spatial audio and randomization. The fire sound effect for the torches could be made 3D, which allows it to have various audio effects depending on the distance/orientation of the object relative the player hearing it. We created a simple volume depreciation over distance with a distance cap, as well as adding a low pass filter to mimic the real world effect where lower frequencies are heard further away from an object than higher frequencies.

The torch example also got into the basics of creating randomization of sound effects. In Wwise, we created a Random Container object, which can hold several audio effects to randomly select from/play as well as modify randomly to give a play effect varied sound outputs. We duplicated our fire sound effect 3 more times in this container (4 in total), and just moved the starting/ending looping times of play in the different audio files to make them feel a bit different. We then also added a pitch randomized variation to one of these sound effects to give even more varied feels (I believe you can also have this on the Random Container itself to apply to all the objects, that might be what the tutorial wanted to do and just misclicked).

When you create these Random Containers, you just make sure to generate the Random Container object and use that as your audio clip. In Unity, you would reference the Container as your sound object and it contains all the information to produce random varied effects based on what you created in WWise.

Overall Wwise seems like a very powerful tool for creating audio effects for your games, especially in the Unity game engine as it has decent integration capabilities.

Unity Player Pref Editor

March 8, 2019

Unity Player Prefs Editor Script

Editor Script

Unity – Player Prefs Editor in Unity

By: Romejanic

As I was finishing my Unity tower defense tutorial, I wanted to look into deleting player pref values to do bug testing for the level unlocking system. When I searched how to do this, I came across this very helpful Unity editor script that gives a few very basic functionalities dealing with player prefs in Unity.

This tool lets you set or get the values assigned to player pref variables you’ve created. This can be useful to double check exactly what a player pref is set at currently. It also has an option to delete the value assigned to a specific player pref, or just delete all player pref values. This gave me the exact option I needed, as well as giving a nice option for checking how the game works for a new player just starting the game.

Tower Defense Tutorial – Brackeys – Ep. 28

March 8, 2019

Tower Defense Tutorial

Episode 28 – Winning Levels

Youtube – How to make a Tower Defense Game (E28 WINNING LEVELS) – Unity Tutorial

By: Brackeys
Ep. 28

This tutorial sets up the system for what happens when the player beats a level.

We began by creating a UI panel for all of the UI that should appear when the player completes a level.

Once we had that setup, we looked into creating some functionality for this screen. This started by creating a RoundsSurvived script to just place on any round counting objects (one in the game over and level won screen) to display the text properly. As an added effect, we wanted to animate the round counter to count up from 0 to give it more of an impact than simply displaying the number.

To get this round counter animation effect, we used an IEnumerator for its ability to WaitForSeconds. We created a while loop that would count from 0 to the number of rounds the player survived one at a time, with a WaitForSeconds of 0.05 each time. This provides the rapid counting effect we’re looking for to spice up the round counter.

The tutorial goes over a bug where enemies could die multiple times because of the fact that Destroy(gameObject) is not a very immediate process within Unity. Since our enemy script just checked if health reached 0 or less to determine if an enemy would call the Die method, which would then destroy it, sometimes this would allow it to call the Die method multiple times if it got shot repeatedly in a small time frame. To solve this, we just added a bool isDead, and have the check to call the Die method see if health is at/below 0 AND !isDead to ensure this is only called once (the Die method sets isDead to true).

PROBLEMS

As indicated in the comments for the tutorial video, there is an issue when selecting the Menu button upon completing a level. The Continue method is where the levelReached Player Pref is updated, so if the player simply selects the Menu button instead, the levelReached is never updated so the player will not be able to select the next level in the level selector.

SOLUTIONS

To keep the levelReached and levelToUnlock variable in the CompleteLevel script (as opposed to the Game Manager) and fix this issue in as clean a way as possible, the comment suggested moving these variable updates to an OnEnable method. This is nicer than just adding it to both methods, and keeps it within the same script which is helpful if I intend on making the GameManager into a prefab in the future.

SUMMARY

  • Rule of Thumb: “Bigger” highlight animations for bigger buttons
  • In Unity, if you want your button to be just text, you can also drag the Text element of it into the Target Graphic of the Button (script) so the text is the specifically clickable area
  • IEnumerators are used when you want a method that can be paused to continue at a later time (can be as small as a frame or two)
  • Destroy(gameObject) in Unity is SLOW. This is always a good piece of code to look around if you are having strange bugs/issues.

Tower Defense Tutorial – Brackeys – Ep. 27

March 7, 2019

Tower Defense Tutorial

Episode 27 – Unlock Levels

Youtube – How to make a Tower Defense Game (E27 UNLOCK LEVELS) – Unity Tutorial

By: Brackeys
Ep. 27

This tutorial gets into creating a system for locking/unlocking levels.

We started by going into our LevelSelector script and creating an array of UI Buttons. This would hold all of the buttons that allow you to select a specific level on the level select screen. We then added a for loop to go through all of these buttons and intitialize them as non-interactible buttons.

To go along with making the buttons non-interactible, we added a Button Disable animation. This was a simple animation that makes the button much more faded out than normal to make it clear that it is non-interactible. To make sure this effect is removed in an interactable state, we added an alpha animation for every other button animation state to just set the alpha back to 1.

Next we needed a way to keep track of the player’s progress to determine what levels they have access to. We wanted this to persist even if the player closes the game, so static variables are not enough. To do this, we need to save data out to a file. We used Unity’s player prefs as the simplest way to do this. We started by creating an int levelReached, which uses PlayerPrefs to GetInt levelReached. When using a get variable command, you also specific a default value to use if there is nothing associated with this value currently (i.e. this is the first time the player is playing the game), so we set that to one so the player will always have access to level 1 initially.

Now we setup that initial for loop that was just disabling every button to only disable buttons if their index (+1) is greater than the levelReached variable. The levelReached variable is now set at the end of a level if the player completes it, increasing the possible level options.

In testing the level select setup, they discovered the bug I mentioned as a possible issue in a previous tutorial. You can sometimes get a scenario where the enemiesAlive in the middle of a wave reaches 0, which signals to our system that the wave is over, even though there are actually more enemies left in the wave. They ended up using my suggested solution as well: just set the enemiesAlive variable equal to the total number of enemies in the wave at the very start of the wave.

They then go over some issues with modifying the game in its current setup. The changes we made in the Game Manager only apply to the current scene, so they have to be redone in every other level (or since we don’t have anything yet, delete the current ones and duplicate the updated level scene). The simple work around for this was to make objects like the GameManager a prefab so when you update it in one scene, it will be updated for every scene. Then, for an even stronger method they suggest is that Unity allows you to put everything that is repeated in each level into its own scene, and only the objects that actually change between levels are their own scene.

SUMMARY

  • Look into serialization for saving player data; many more advanced games use .json or .xml to store player date
  • Unity uses Player Prefs to do a very simple version of saving data
  • When using get/set variables, make sure to use the EXACT SAME identifier name for the variable. This will not generally return an error if entered incorrectly as it will just set it to the default value instead.
  • Unity has a system to let you load different scenes in at once, look into properly using this feature (this was the suggested ideal method if you want to create a lot of levels)

Tower Defense Tutorial – Brackeys – Ep. 26

March 6, 2019

Tower Defense Tutorial

Episode 26 – Fading

Youtube – How to make a Tower Defense Game (E26 LEVEL SELECT) – Unity Tutorial

By: Brackeys
Ep. 26

This tutorial gets into creating a level select menu for the player.

This would require its own scene, so we duplicated the Main Menu scene as a place to start since it’s already fairly empty. We started by setting up the hierarchy of UI assets for the level content selection area. It was noted that this is a general way to setup a scrolling menu for selecting objects in Unity.

The hierarchy is as follows:

  • UICanvas
    • Title
    • Levels
      • ScrollRect
        • Content

We then added a button to our Content UI object, and gave that object a Grid Layout component. This allows Unity to place everything in an even grid layout for you. We also added a Content Size Fitter. This helps allow the object it is attached to scale to fit the content placed in it. We also made sure to move the pivot anchor point of this UI object to the top of the object to make sure it scales downward from that point instead of out from the center.

We added a bunch of buttons to help see that all of the scaling and clipping was working properly with the UI elements. To help keep them from flowing out of the menu (which also works with the idea of creating a scrolling menu), we added a Rect Mask 2D component to the ScrollRect object which blocked out child objects that were not within this rectangle space.

Speaking of scrolling, we added the Scroll Rect component to the ScrollRect object next. This just required dragging in the ScrollRect object as the viewport and the Content object as the content to start this working. This did have a slight issue for me where it seemed that I could only scroll if I clicked/held on a button in the content area. If I clicked/held on an empty space within the content area, I could not scroll the menu, so that would have to be fixed.

We created a simple LevelSelector script and placed it in an empty gameobject. This script provides the method for the onclick event for each of the buttons to reference to take the player to the corresponding level. To help test this, we just duplicated our initial level and changed the number of lives to create a level 2.

Finally, we added a scrollbar component to the Levels object to go along with the scrolling of our scroll rect. It just gives another, clearer option for scrolling, especially for someone using a computer.

SUMMARY

  • Check pivot/anchor point locations for scaling UI elements, especially those using a component like Content Size Fitter.
  • Implementing scrolling into UI elements in Unity is straightforward with ScrollRect and Scrollbar components.

Tower Defense Tutorial – Brackeys – Ep. 25

March 5, 2019

Tower Defense Tutorial

Episode 25 – Fading

Youtube – How to make a Tower Defense Game (E25 WAVE SPAWNER 2.0) – Unity Tutorial

By: Brackeys
Ep. 25

This tutorial focuses on updating the wave spawner to be a more useful and versatile tool.

One of the first changes was to have the next wave spawn some time after the previous wave has been killed off instead of having it on an overall set counter. We create a public static int, EnemiesAlive, to constantly hold this value of how many enemies are alive in the current wave. We then let the Die method in the Enemy script and the EndPath method in the EnemyMovement script remove one from this value before destroying the enemy object. Since we are already referencing this in multiple somewhat unrelated areas, I think there might be a nicer way to reference one method somewhere that destroys the enemy gameobject as well as removing one from this global counter.

Another issue I am already noting here are that there might be strange cases where the enemy is killed almost immediately upon leaving the spawn, so enemies will be 0 already at that time and this may start the next wave spawning. It may be better to have the system just know how many enemies will be in the wave ahead of time and set the EnemiesAlive value to that at the very start of the wave, then subtract from this value when enemies are destroyed and let the next wave start when that value is 0.

Currently the WaveSpawner only holds a single enemy prefab to be the enemy to spawn. As most tower defense games do, we want to have a system that can spawn multiple types of enemies. To begin, we created a new Wave Class to hold the information needed for any particular wave. Since this is its own unique class, make sure to remove the Monobehaviour tag from the class. We also added [System.Serializable] to this class so it would show up in the editor. The values we created for this were:

  • public GameObject enemy – to hold the enemy prefab to spawn for this wave
  • public int count – to determine the number of enemies to spawn in this wave
  • public float rate – how fast each individual enemy in the wave spawns (1 over time between spawns)

To continue on the thought that we want to be able to have control over the individual waves, including having different enemy types, we created an array in our WaveSpawner script to replace the single enemy prefab gameObject we had before. This array would also be an array of the Wave class instead of gameObjects.

”It’s not as automated… but it gives us so much more configuration possibilities and really allows us to create something that’s much more fun for the end user. Having this idea of a wave that is kind of an object that we’ve created on our own with these different characteristics, then storing a bunch of these waves in a list, then going through them one by one and using some of the properties in there to create different behaviors is kind of the core of object oriented programming.”

Now our IEnumerator method SpawnWave grabs the next Wave in our array of Waves and uses all of its information. The enemy prefab was replaced with wave.enemy, the time between spawns was replaced with 1/wave.rate, and the number of times to go through the for loop was changed to wave.count.

Finally, to take advantage of this new system, we created some new enemy types, Tough and Fast, to go with our existing enemy which is now just the Simple enemy type. We created an entire Enemy folder, then gave each type of enemy their own folder to hold the gameObject prefab, the material, and the particle system death effect for that specific enemy. This seems like an effective organizational pattern to follow for holding different enemy types.

To edit the individual waves we want to create, we currently did that in the editor. In our WaveSpawner script, since we made the Wave class serializable, we could see our Wave array along with all the individual public variables associated with the individual waves in the array. We had to go to each one specifically to enter the enemy prefab for that wave, the number of enemies to spawn, and the rate at which they spawn. While this does give us a lot of control, there may be efficient ways to automate some of this process for longer scaled gameplay.

LEARNING PRACTICE

Good practice for learning to use your own classes: create a pretty basic method for a core functionality (like our spawner), then try to replace some of the main variables in it with those in a user defined class you make (like our Wave variables that replaced those in the spawner script). This is basically what we did in this tutorial since we had a very bare bones spawner but then updated it to work better with various types of enemies instead of just one. It really helped me understand, not only how to use a user defined class, but also how to effectively set one up.

SUMMARY

  • Keycode Shortcut – Visual Studio: with a piece of code highlighted, hold Alt + arrow key to move that code up or down a line
  • When you know you will create a lot of a certain type of object, creating a class that holds the key properties for that type of object is necessary
  • Newer versions of Unity allow for Prefab variations which might be worth looking into for our enemy prefabs (New duplicated versions worked fine for now though)

Tower Defense Tutorial – Brackeys – Ep. 24

March 4, 2019

Tower Defense Tutorial

Episode 24 – Fading

Youtube – How to make a Tower Defense Game (E24 FADING) – Unity Tutorial

By: Brackeys
Ep. 24

This tutorial focuses on creating an overall fading effect for the game.

We created an empty gameObject, SceneFader, and added a UI Canvas to that, which we then added a UI image to that is just a black image.

Then we added a SceneFader script to our SceneFader object to handle the fade effects. We used IEnumerators to handle the fading methods. We used the IEnumerator for its ability to wait certain amounts of time. The IEnumerator FadeIn uses a yield return 0; line in its while loop so that it updates at the same rate as update (every frame). Yield return 0 basically tells it to wait a frame.

We created a variable of type AnimationCurve, which gives us access to a curve we can manipulate by changing its shape or adding/removing points to control how a value fluctuates. We used this to control the FadeIn IEnumerator. We then duplicated this IEnumerator to create a FadeOut version as well (just swapped the values in the while loop to run the other way to make the rest of the code consistent). FadeOut was then added to a public method, FadeTo. The both receive a string variable that corresponds to the scene name of what scene they should be fading to.

We then just went to all of the scripts/menus where we move between scenes and added this FadeTo call from the SceneFader. This included the pause menu, game over menu, and main menu. This also included making sure to drag our SceneFader into the reference for all of these scripts since they did not want to use FindGameobjectOfType for computer processing reasons.

My thoughts on why an IEnumerator was used here is that they seem to be good with dealing with something you want to happen over time, and they can run while other actions are running/processing. Since we just wanted a fade effect, it’s helpful to let everything else continue to run as opposed to interrupting something to finish this effect. The time element basically lets us have a pseudo”Update” method that only runs for a certain amount of time and then never needs to check again.

SUMMARY

  • If you want a UI element to cover everything (including other UI elements) make sure to check the Sorting Order
  • I still need to look into IEnumerators to get a better grasp on their specific uses

Tower Defense Tutorial – Brackeys – Ep. 23

March 2, 2019

Tower Defense Tutorial

Episode 23 – Enemy Health Bars

Youtube – How to make a Tower Defense Game (E23 HEALTH BARS) – Unity Tutorial

By: Brackeys
Ep. 23

In this tutorial we created health bars for the enemies.

We began by creating the foundation for the UI asset. We created a new World Space canvas, added a child UI Image object as our health background, then childed a UI image to that that would be our actual health bar. The BG was given a transparent black color, while the health bar was a fully opaque light green.

We then childed this full group of UI assets to our Enemy prefab. The position needed fixed when this was applied, and the scaling reset so I had to reset that manually as well. This created a health bar that would follow our enemies now. We would need a bit of a tracking script if our enemies rotated (so the health bar would not), but currently the enemies don’t rotate at all so this is not necessary.

To make our health bar actually do something, we started by dragging in a white square image to the source image of the health bar UI image, which was created for the tutorial. It was just a simple 2 x 2 white square. We then changed the Image Type to Filled, and selected the Fill Method “Horizontal”. This allows us to control how much of the image is “filled” horizontally, between 0 and 1 (0 – 100%). This has a very similar effect to what I usually script for health bars which is just a scale multiplier between 1 and 0 tied to the x scale of an object with the anchor point located all the way on the left/right. Either way, this still needs to be tied into health scripts.

Our fill amount for this health bar image needs to be between 0 and 1, so we need to represent our current enemy health as some fraction of our enemy max health. This is easy enough to do by simply holding a value for the max health and dividing the current health by the max health.

PROBLEMS

Bug

I found a bug where some of the turrets I was placing could not be upgraded. They were base turrets but when I selected them it already said they were “Maxed Out” and I could not upgrade them. It was only a select few turrets, and I realized they were in locations where I had an upgraded turret previously and sold it to make room for a new turret.

I believe this bug is simply caused by the fact that the state of upgraded is tied to the node location, so when we upgrade and then sell, the upgrade state is not being reset. That should be a simple fix of resetting the upgrade state when the Sell method is invoked.

Solved

This appeared to be the case as the bug hasn’t come back since I simply added a line to set the isUpgraded bool to false in the Sell method of the Node script.

SUMMARY

  • Another way to create health bars: under the Image (script) component; select image type Filled, and choose Fill Method “Horizontal”

Tower Defense Tutorial – Brackeys – Ep. 22

March 1, 2019

Tower Defense Tutorial

Episode 22 – Main Menu

Youtube – How to make a Tower Defense Game (E22 MAIN MENU) – Unity Tutorial

By: Brackeys
Ep. 22

In this tutorial we created the Main Menu scene for the game.

We duplicated the original game scene to start, and deleted out everything except the Light, Main Camera, and Environment. Then we only kept the Ground Plane from the environment. We then added a Standard Turret Prefab to be a central object for our menu.

We then edited the sky box to something other than the Unity default. We selected Solid Color for it, and used the color picker to pick the top most color of our ground plane so the sky matched this very final gradient of color. This made it seem like the background was one solid, endless color gradient for the most part.

We then created a World Space canvas with text fitted to it for our PLAY text. We placed this on top of the turret prefab in our menu. We then wanted to make this text clickable, so we just added a Button (script) component. This basically turned the text into a button for us. We could even add our previous animation by simply adding an Animator component and selected our Button Controller for the Controller.

We then created the MainMenu script which will hold the main functionality of this scene. This started by creating public Play and Quit methods for our Play Button and Quit Button. Quit was just Application.Quit, and Play loaded our MainLevel scene.

Finally, we added a bit of animation to our Main Menu to utilize the fact it is set in a 3D environment. We added the two button canvases as children to the PartToRotate object of the turret, and created a quick animation for that that just rotated the entire turret and UI element back and forth a bit over time. This really made the menu feel alive and 3D.

SUMMARY

  • To set current editor view as camera view: select camera and press: Ctrl + Shift + F
  • Set skybox to solid color and use color picker to select farthest/top most color of ground plane for a quick/easy way to make ground and sky look like one coherent background
  • When referencing scene names, make a string and set its value to that scene name so if at any point you want to change the scene name, you just change that string variable’s value and it will fix it in all locations needed

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).