Softskill Plans and Improvement

As Studio 1 began, I became focused on the work that presented to me. Throughout Project 1 I focused too heavily on creating art assets and throughout Project 2 I prioritised the completion of group work over personal work.

My problem was that I didn’t have any personal management. Whenever I had time free to work on something, I found that I spent a lot of time just figuring out what I needed to work on. I always knew what group work I had to do, thanks to Hack n Plan, but when it came to write Dev Diaries or report my work, I struggled.

To help remedy this, I created a personal Hack n Plan where I listed all of the work that I had left to do. Anything from Dev Diaries to Audio to Scripting were placed in the Hack n Plan. It was a valuable tool for organising my free time and making me far more effective at completing my work.

It allows me to track my remaining work and monitor my week-to-week work ethic. The time spent updating Hack n Plan is more than made up for by the amount of time I save when finding something I want to work on.

I also attempted to use a work calendar, along side Hack n Plan. I found it useful at the start but, once I had memorised the times that I had set aside to work, I found myself not using it very often. I found that I worked better when I kept Hack n Plan opening, using it as a visual reminder of all of the work I had to do.

I plan on using Hack n Plan as often as possible. As it is now, Hack n Plan has been a valuable tool in helping me finish all the work that I needed to do. Additionally, I believe that, once I am more familiar with Hack n Plan, I can gain the benefits of a work calendar from Hack n Plan as well.

Coding the Player

Project 1 was a solo project, so it was up to me to make or source everything. The most involved script that I had to write was my Player script. It controls player movement, player animation, player attack and more. I am going to go through exactly what my Player script does, as well as the scripts that it is dependant on.

First off, let’s go through the references and variables.

PlayerCode1.png In my references there are three that are assigned in the Start() function one that is assigned in the Inspector and another that is assigned later, in the Attack() function. Of the three that are assigned in Start(): the Rigidbody2D is used to move the player, the Animator is used to change which animations are applied to the player and the AudioManager is used to play audio. The bullet GameObject is used as a base in the Attack() function.

Next are the variables playerSpeed and playerHealth. The variable playerSpeed is a factor in how fast the player moves and playerHealth determines how much damage the player can take.

 

Now on to the functions that are called in FixedUpdate(). The first function called is Movement().

PlayerCode2.png

This function is a list of if, else if and else statements. If one of the first four statements is true, then the player moves in a direction dependant upon which key is press. Pressing W, A, S or D moves the character up, left, down or right. Each statement also determines whether or not the bool ‘Moving’ is true.PlayerAnimation.png

If the ‘Moving’ bool is true, then the character transitions from whatever state they are currently in to the ‘PlayerWalk’ state. When the character is in the ‘PlayerWalk’ state, the character sprite plays a looping 2 frame moving/walking animation.

 

The next function is the Attack() function.

PlayerCode3.png

This function only runs when the player clicks the left mouse button. When that happens, a Vector3 is made that contains the X,Y and Z coordinates of the mouse cursors current position. Then the Z coordinate of the Vector3 is reduced to 0 (since this game is 2D). After that, the Vector3 is changed from screen coordinates to game coordinates.

Now, a copy of the bullet that was previously referenced is spawned and assign to the bulletPrefab reference. The bulletPrefab is then rotated to face the mouse cursor. Then force is applied to the bulletPrefab’s rigidbody, making it travel toward the location that the player clicked.

As well as spawning and firing the bulletPrefab, a sound effect is played. You can read more about that in my pitch shifting audio blog.

Finally, after a two second timer, the bulletPrefab destroys itself.

 

The bullet has its own script as well. It detects if it collides with anything and, if so, tells them to take damage and then plays audio.

BulletScript.png

The Bullet script references and assigns the AudioManager, since it plays audio when it collides with certain objects. There is also a variable that determines how much damage the bullet does.

The OnCollisionEnter2D() function retrieves the tag of the object that it collides with. If it collides with an object tagged either Enemy or Enviro, it will tell them to take damage, play a sound effect and then destroy itself.

 

Now, back to the Player script.

PlayerCode4.png

Both the ApplyDamage() function and the Death() function are in all scripts that have the ability to take damage and be destroyed. When a variable named damage is sent to this function, it reduces playerHealth by an amount equal to damage. Then if the variable playerHealth is less than, or equal to, 0 the GameObject that this script is attached to is destroyed.

Pitch Shifting Audio

I have added further to Project 1. I decided to make three more sounds effects. There is now a sound effect for: an enemy getting hit with a bullet, firing a bullet and destroying the environment.

As usual, I opened Audacity and recorded three different tracks. If you would like more info on how I did this, you can check out my previous audio blog.

AudacityBulletRip.png

I then exported all of the tracks and named them Bullet, BulletHit and Rip. Then I moved the exported files into my Unity project.

The first thing to do was to add more public references to the AudioManager script. So now my script looks like this:

AudioManagerCode.png

Then I can just drag and drop the audio files that I have into the appropriate spot in the Inspector.

AudioInspector.png

Now for the interesting part. To make the audio change pitch when it play, all we need is one line of code.

PlayerCodePitchAudio.pngI put that one line of code in the Attack() function in the Player script, which might seem familiar if you have seen some of my other Project 1 blogs.

It is line 62 that does all the work. When the bullet shoots, it travels toward the mouse cursor and plays the ‘bullet’ sound effect at a pitch that ranges between 0.6 and 1.4 (with 1 being the original pitch). The pitch changes every time the player shoots a bullet.

However this setup has a flaw. Since all audio plays through audioManager.audio, every sound effect is going to play at the same pitch as the last bullet fired. There are two ways to solve this and one way takes much longer and requires more work than the other.

The more difficult option is to add an extra line of code to all scripts that play audio. In this case I have five other audio clips whose pitch I don’t want to change. This means that every time I use audioManager.audio.PlayOneShot() (the same function is on line 63 in the code above), I need to add the following code on the line above it:

AudioHardFix.png

This line will change the pitch back to 1 meaning that the next line, the line to play audio, will play at the normal pitch.

The easy fix is to add an extra AudioSource to the AudioManager GameObject. After doing so, the AudioManager code will also need to change to the following:AudioManagerEasyFix.png

The Start() function that found the AudioSource will not work anymore since there are two AudioSources. So instead, we remove the Start() function and add another public reference for the second AudioSource. Now we can just drag and drop the AudioSources in the Inspector.

Finally, lines 62 and 63 in the Player script change to:

PlayerAudioEasyFix.png

Instead of playing the audio through audioManager.audio, it now plays through the second AudioSource audioManager.bulletHit. Also, only the Pitch of the second AudioSource is change. This means that all audio played through the first one will not have a change in pitch.

Improving Enemies with Particle Effects

Yet again I am back on Project 1, making improvements. This time I decided to add some more visual features to the enemies. I wanted to make the enemies stand out because they can be hard to see, since both the enemies and the background have similar cream colours. Also, since the enemy sprites just disappear when they have lost all their health, I wanted to have a fade or a transition just so it looks better.

What I added is a particle effect that sits behind an enemy and fades after the enemy dies. The effect is intended to make the enemy appear as if they have an aura.

To do this I created a Particle System in Unity, set its Shape to Mesh and its Mesh to Cylinder.

ShapeMesh.png

The reason I selected Mesh > Cylinder instead of Circle is because particles spawn in the centre and around the edge of the Cylinder, whereas Circle has particles spawning inside the Circle. You can see the difference below.

ShapeCompare.png

ShapeCompareSettings.png

The Particle System on the left is the Cylinder and the Particle System on the right is the Circle. Both have the same settings, which you can see in the image above.

The Cylinder Shape suits my needs more because, when speed is set to a negative, all the particles centre in a single spot. This gives me the kind of fading effect that I am looking for. Below is an image of the Cylinder Particle System with Start Speed set to -0.5 and Emission > Rate Over Time set to 500.

Cylinder.png

For the actual Particle System I used the following settings and got the following result:

CylinderSettings.png

CylinderDone.png

Now to put the Particle System underneath an enemy sprite.

CylinderSprite.png

In order to make the Particle System linger and fade after the the Enemy sprite has been destroy, we need to write some code. We can’t make the Particle System a child of the the Enemy sprite because when the Enemy sprite is destroyed the Particle System will be destroyed as well.

The first that we have to do is reference the Particle System.StopLoopCodeStart.png

Also, set up a bool that we will use later.

StopLoopCodeBool.png

Then, in the function that controls when the enemy is destroyed, line 41 of the code below retrieves the Main section of our Particle System and line 42 retrieves the Loop setting of our Particle System and changes its value to the bool made earlier.

StopLoopCode.png

Be sure to put the code above the Destroy code, otherwise the Enemy will be destroyed and will not run anymore code.

Now we have a Particle System that fades when the Enemy sprite is destroyed, but what happens when the Enemy sprite moves? Well the Particle System, at the moment, doesn’t follow the Enemy sprite. Let’s change that.FollowCode.png

The above code has a public reference to a GameObject, meaning that we can drag and drop the specific Enemy sprite that we want to be associated with this code. Then the Follow() function finds the Enemy’s position, if available, and makes the Particle System’s position equal to it. Finally, this function is called in Update().

Now the Particle System follows the Enemy sprite and fades away shortly after the Enemy sprite is destroyed.

Creating Audio Assets

In addition to art assets and particle effects for Project 1, I decided to create my own audio assets as well. Using Audacity, I created the sound effects for when an enemy gets destroyed and when and enemy attacks.

To do this, I opened Audacity and click the ‘Click to Start Monitoring’ button up the top. This is just to set up my mic and make sure that everything is recording properly. From there I hit the record button and made a few noises that I thought would be appropriate.

Audacity.png

After I found a few that I thought were good enough to use, I deleted all the excess audio and dead-air by clicking and dragging the mouse cursor over the areas and then pressing the Delete key.

Next I had to cut the audio in three different sections. This is because there were three different sounds in that audio clip that I want separated and if I was to export the current recording, it would export in one large chunk which I would rather not work with.

To cut the audio, I highlighted a section that I wanted to keep and pressed the Space Bar. What the Space Bar does is it plays the currently selected audio and nothing else, meaning that you can check if you have selected all the audio you wanted.

AudacitySelectedAudio.png

Then, once you are happy with your selection, you go to Edit > Remove Special > Split Cut.

AudacitySplitCut.png

This cuts the audio you have selected out of the current track. Now you need a place that audio in a different track. To do this you need to go to Tracks > Add New > Stereo Track.AudacityAddTrack.png

This will create a track beneath the first one on the screen. Now you need to paste the track that you cut by clicking on the second track and then going to Edit > Paste.AudacityPaste.png

You must follow these steps for each separate audio file that you wish to create. Remember that each track is a different audio file. When pasting audio, it may sit beyond the beginning of the track but that is nothing to worry about. Since there is nothing recorded there, not even dead-air, Audacity disregards that section completely. However, if you want to fix that you can go to Tracks > Align Tracks > Start to Zero and it will move the audio on the track to the beginning of the track.

Now that all the audio is ready, we can export it. We are able to export multiple tracks at once by going to File > Export Multiple. When you click that you will be greeted by the screen below.AudacityExportMultiple.png

Note that I am exporting the audio as MP3’s. When I first tried this I was given a pop-up telling me that I needed the LAME encoder in order to export my audio as MP3’s. This isn’t a big problem because the pop-up as a button on it that directs you to the download page for the LAME encoder.

After doing that, it will ask you to enter any info that you want on your audio files such as Artist Name, Track Title, etc. Once that is done and your files are successfully exported, it is time to import them into Unity. I made a folder called Audio and placed all of my tracks in there.

Now there is audio in the project but not in the game. Time to add some functionality through code. I started by creating an empty and naming it ‘AudioManager’. I gave it an AudioSource and attached a script to it that looked like this:AudioScript.png

This script has public AudioClip refenences that allow me to drag and drop my audio from the Inspector and an AudioSource reference that is assigned to when the script starts. So now we a place in the game where audio is stored and can be played from, but nothing that tells the AudioManager to actually play anything.

The next step is then to add lines of code that tell the AudioManager to certain tracks when a certain thing happens. The two images below are of the lines I have added to the enemies Death and Attack functions.

EnemyAudioScript1.png

EnemyAudioScript2.png

The first script tells the AudioManager to play ‘defGhst1’ whenever an enemy dies and the second script tells the AudioManager to play ‘defGhst2’ whenever the player enters the enemy’s range of attack.

Creating a Particle Effect

Particle Effects:

For Project 1, I created a particle effect that changes based on whether the player has finished the level or not. The purpose of this particle effect is to have a more visually appealing indicator that the level is complete and that the player can move to the next one. I also wanted the particle effect to match the art style of the game, which is pixel graphics. Note that this project was done in 2D.

I started by creating a Particle System in Unity by right-clicking inside the Hierarchy and selecting the Particle System option.

HierarchyParticle.png

Doing this will make a GameObject called Particle System appear, similar to the Particle System that, as you can see, is a child of the ExitLevel GameObject.

The default Particle System shoots white circles in a cone shape, as can be seen below. However, this doesn’t fit well with the current theme of the game.

SceneParticle.png

So, to fix this, the first thing I did was to change the Material in the Renderer settings. I want this particle effect to mimic a section of the border so I created a Material that is the same colour as the border and applied it to the Particle System, the result of which you can see below. Note, however, that in order to get this result I had to change the Shader that is on the Material from Standard to Unlit > Color.

SceneParticleMaterial.png

The next thing that I changed was the Shape. The default shape is a cone but, in order to make a believable-looking wall, that will have to change. After experimenting with a few different shapes, I settled on the Edge shape.

The first thing to adjust is the rotation. The default X rotation of a Particle System is -90 degrees which means that, with the Edge Shape applied, the particles are now shooting towards the camera, if in the 2D camera setting. Set the X rotation to 0 to stop that. So now the Particle System should look the the one pictured below.

SceneParticleEdge.png

Now, while that seems all well and good, it doesn’t mimic a wall very well. The first step to fixing this is to position the Particle System where I want it and adjust its value from there. As you can see in the picture below it doesn’t fit quite, since it is supposed to fit in the small opening in the border below it.

SceneParticlePlaced.png

The first setting I change was the Start Size, to 0.1, since those particles are far too large for what I need them to do. Then I went to Shape > Radius and changed it to 1.8 in order stop the particles from extending into the border. After that I did some tinkering with both Start Lifetime and Start Speed, finally settling on 1 and 0.66 respectively.

The Particle System now looks like the image below. There is a fairly obvious problem here, that problem being that there aren’t nearly enough particles to make a convincing mimic of a wall.

SceneParticleAdjusted.png

In order to add more particles, I went to Emission > Rate Over Time and changed it to 10,000. This, however, isn’t the only setting that must change. If you don’t change Max Particles to 10,000 (Rate over Time multiplied by Start Lifetime) as well, you will get a solid line of particles once every second instead of a block of particles.

The image below is a big block of 10,000 particles. Now, all that remains is adding some functionality through coding.

SceneParticleDesignDone.png

Here is what I have written for the Particle System:

ParticleCode.png

The first thing I do is reference the EndLevel script because there is a function in there that detects if all the enemies have been defeated. Then I wrote a public reference to the Particle System. This allows me to assign the Particle System in the Inspector. Finally, the float partiChange determines the rate at which the Particle System decreases emission.

The function LevelComplete() check if all the enemies are defeated and, if so, retrieves the emission and then the emission.rate of the Particle System. I then change the constantMax of the emission.rate so that it decreases according partiChange. Then, last of all, is an if statement that checks if the constantMax goes below a certain point. If it does go below that amount the rate that constantMax decreases at is set to 0, meaning that it remains at the rate that it dropped to.

This script is then attached to the ExitLevel object that was in the Hierarchy from earlier. Now the Particle System is done and this is the final result.

Project 1 – Post-Mortem

Project 1 involved each student receiving an artist to research. Each student must then adapt the game Berzerk (Atari) to their given artists’ style. I was given Harriet Powers, an African-American woman who made quilts depicting biblical stories in the late 19th century. I decided to adapt Berzerk by using the panels of Powers’ quilts as levels in the game. I used Unity to create this project.

This was the first project of Studio 1, which started development in early February and ended in late February. While I was supposed to submit the project at the end of February, I held off on submitting it in hopes of being able to continue work on it later. Unfortunately I didn’t have much free time over the trimester to work on this project, so not much progress was made.

 

What Went Right:

Art Assets:

For this project I decided to create all of the assets by myself. I managed to make all the art assets that I needed and I even added some animations to the player and to the enemies. It felt great to branch out and expand my skillset. I learned how to use Pyxel Edit for sprite work and sprite animation work.

The reason why this happened was because, over the holidays, I took an interest in a certain aspect of streaming culture. That aspect being fan-art. A streamer that I was watching had 2-3 people in their chat that would occasionally draw quick pieces of fan-art. I saw it as an interesting way to improve skills as well as contribute to a community. So that inspired me to find programs that I could use. By the time uni came around I was excited to use those programs for my projects.

What I can take away from this is that finding a passion outside of profession can positively impact my work, especially if that passion could be used in my profession. Also, I am typically very lazy after coming back to uni after the holidays. However, since I found something productive to do over the holidays, I maintained the working mindset while still enjoying myself.

 

What Went Wrong:

Prioritization:

I spent a lot of time creating all the art assets and, unfortunately, I didn’t leave enough time for the rest of the game. So, when the time came to move on to the next project, I was left with 11 levels but little gameplay. What’s worse, because of how I set up the levels, when I came back to the project it was hard to add the work that I had done to the first level to the rest.

The reason why this happened is because I didn’t have any planning or management properly set up and let my eagerness to create assets supersede the other aspects of game development. Since there was no plan in place, it was hard to estimate just how long it would take to make all the assets. When all the assets were done, I was left with very little time and not much else to go on.

What I can take away from this is that I always need to set up a plan before working, regardless of the amount of work that I need to do. It will help me remember what needs to be done as well as prioritise work by its importance.

Pitching A Stitch In Time

I recently pitched my game idea, A Stitch In Time, to my fellow peers at SAE QANTM. My game is a fusion of Berzerk (Atari/Arcade game) and Harriet Powers’ art style. You can find a recording of my pitch here.

It isn’t my best performance but, considering that I hadn’t slept the night before, I think it was acceptable.

I received some rather interesting feedback from my peers after my presentation. Someone asked if I might be overscoping the project, which is worrying because I have been prone to overscoping before. Some also requested that I look into, and draw inspiration from, more of her works. While this is generally great advice and I would be more than willing to take it on, the two quilts that I showed in my presentation are the only existing examples of her work. I didn’t make that clear in my presentation however, so that is my mistake.

Concerning overscoping, I have considered cutting the mechanic that draws enemies, that haven’t been killed, from the previous level and into the next level when the player transitions. I would consider adding this feature back into the game if I had any spare time after the project was completed but, as it stands, there is already plenty of work to done.

Another questioned the scoring system that I was going to use, stating that, even though $10 is relevant to the time period, it seems rather small and that I should check how much it would sell for today. After searching around, I found that replications of the Bible Quilt were made but finding a price for one is hard to come by. So instead, I shall convert $10 in 1898 to what it would be worth now, meaning $285.

Some were concerned that angels and demons don’t fit well with the theme of the game, suggesting that replacing demons with colonial white people would be more appropriate considering the era of the art piece in question. I agree that this change would better suit the kind of game feel that I am trying to achieve and, to further increase that feeling, replacing the angel with Harriet herself would be better. This change would also allow me to add an appropriate life system into the game by giving the player as many lives as Harriet had children (9).

The final question was concerning Evil Otto, a type of unkillable boss character that would spawn if you took too long to complete the level. I won’t be putting a version of Evil Otto in my game in order to focus on completing other elements.

Dev Diary – Creating 2D Assets

For my first project of Studio 1 (one of my subjects at uni), I decided to take on the task of creating all the games assets by myself. Quite a daunting task but I felt that, given the simple shapes that my artist used in her works, it wouldn’t be too difficult to create something that, at least, vaguely matches hers. What sparked this drive was actually a program that I had purchased from Humble Bundle called Pyxel Edit. I am not too sure of this program’s reputation at the time of writing but I was excited to start creating my own assets, instead of relying upon Unity’s Asset Store.

While I found it easy to adapt Harriet’s artwork and style to the program, my lack of knowledge when it comes to pixel art in general was quite evident when I began to import my assets into Unity. When I began my first import I had finished approximately half of all the assets that I had needed. While that sounds all well and good, I soon realized that my assets were far too small for my intended screen size, as they were a measly 64×64. This led to me redoing all the assets that I had done previously but in a much larger canvas, 264×264.

I also attempted some simple animations while re-creating the previous assets. I was able to animate both the player and the enemies, even if it is just one extra frame. I learned the process of creating a sprite sheet, albeit a small one, as well how to import my own assets and animations straight into Unity. While assets are simple to import to Unity, the animations required a bit of additional work. Since the animations are imported as a single sprite, I had to enter the settings of the animation in question and split the sheet into multiple cells that Unity could recognize. Since my animations were a simple two frames, it was easy to understand what I needed to do, but that process allowed me to understand more complex sprite sheets and how to use them in later projects, if need be.     

Environment:someportal Player Animation:Player.gif