Observations from the Unity3D Space Shooter Tutorial using 2017.1
I’m starting this Space Shooter tutorial now and I’m going to log my comments, thoughts, impressions, and observations here in order to help others (and my future self) best leverage this material. The Space Shooter tutorial was created by the Unity3D team in 2013 using the latest version of unity at the time. Since the tutorial is four years old it has experienced substantial “tut-rot”* so in this article I’m going to use my Code-DeLorean to bring this space shooter into 2017 and make it work with Unity3D version 2017.1. Since this is in some sense a walkthrough of a tutorial, I’ll call this a Meta-Tutorial*.
* Tut-Rot – Tutorial Rot – The incompatibilities created as a result of toolsets upgrading while tutorials do not.
* Meta-Tutorial – Just coined it! See above for the explanation.
* Code-DeLorean – Bringing old code up to speed with new tools.
For Further Information
If you have trouble that isn’t addressed in this article, visit this thread on the Unity Forums which has 53+ pages of Q&A all entirely specific to this Space Shooter Tutorial. There is also a Unity 5 Upgrade Guide which is linked from the main tutorial page which describes some of the differences between the video and the current version of Unity, however its … well … spotty with messy formatting, missing letters and words, etc. I’m guessing it was based on a poorly done export of the youtube annotations of the tutorial videos, but the guide is certainly more explanatory and helpful than the annotations alone.
Lets Get Started!
While in this article I’m being picky about the details of the tutorial, I am actually a fan of this tutorial (evidenced by the time I’m taking to dig into it and write this article). I am glad the author created it and I think that combined with this article the tutorial will be useful to you. Lets Get Started!
Gathering the Assets
On the main Space Shooter Tutorial page: there is a link which purports to let you “download the assets for free” however sometimes that link inexplicably (though reproducibly) takes me to the main asset store page from whence I must search for “Space Shooter Tutorial” to get to the intended location.
Afterwards there is a link to “Download” or “Open In Unity” and a process of putting the content into a download manager queue, downloading it, then opening a new project with the new content you’ve downloaded. THEN from within the new project it asks you to download the content again.
There are various dialog boxes and buttons to click and none of it is too complicated but all told I found this step confusing and potentially frustrating and it delayed me to the tune of 2-3 minutes. Still in a good mood (probably since I just got engaged to be married … YAY!) I proceeded to the next steps.
Setting Up the Project
This video goes into some detail about how to create a blank project. There is a short section about importing the Space Shooter Tutorial content which has rotted entirely and it doesn’t seem to show anything about how to do that part so you’ll have to poke around a bit. It shows how to change the screen resolution of your final published game and also has some good discussion of build settings and of editor layouts and how to save them.
A slight discrepancy between the video and the latest version of Unity3D is the non-existant “project creation wizard” that they speak of. A totally forgivable Tutorial-Rot problem which I think most people will be able to figure out.
From the Video:
From the latest Unity 2017.1
Note: Since I hadn’t installed the WebGL platform when I installed Unity I had to do that during this step. There was a convenient link in the Build settings which let me download the package for Mac, and the installer worked well even when I had Unity still open, however I had to restart Unity for it to really recognize that it could publish to WebGL.
The Player GameObject
This section has a number of youtube annotations that provide corrections to the instructions given in the video and although most of them aren’t that critical, Youtube annotations aren’t typically visible on mobile devices so keep in mind that you may be missing a few things if you are watching on your phone most notably:
In my case without ‘convex’ selected, the mesh collider didn’t even show up in the scene view!?!
Camera and Lighting
This video adds in three directional lights to make the ship look like it is lit from a bright star off to the right but also enough ambient and ‘rim’ lights to be able to see the ship clearly during gameplay.
When this part talked about removing the directional light and skybox I got momentarily lost because the ambient lighting menu is VERY different now, however one of the annotations in the Youtube video pointed me in the right direction: Window(Menu)->Lighting->Settings. From there although he talks a lot really all you need to do is make the ambient lighting totally black.
Late in the video an annotation pops up suggesting that due to changes in the engine’s lighting pipeline you should set your lighting intensity to about double what is suggested in the video. I had to go back and set the main light to 1.5 instead of 0.75 and when I did everything looked much better.
Adding a Background
This video shows how to add an image (aka texture) to a flat mesh called a quad to create a background and also speaks of how to properly arrange, and scale that mesh, and how to light it without affecting the lighting that applies to the ship. At the end we move the background down and out of the way of the ship which interestingly doesn’t affect how the camera sees the background since we previously set it to ‘orthographic’.
Get the ship moving
Now we’re finally adding some gameplay. I feel like this would have been cool to have going in the first or second video because its motivational to see things actually happen in game. This section uses a clever (though ultimately really simple) mapping of input values to velocity to move the ship around using physics.
Its impressive to me how easy it is to get the ship moving. This video talks about how to speed up the movement of the ship using public variables and how to set those inside of the unity editor (so you don’t even have to touch the code to change the value) by exposing the public variables to the Unity Inspector. One thing I noticed was that you can actually change the speed value WHILE you are playing the game to test out different values and see which one you feel best suits the gameplay. He shows something cool about [System.Serializable] which is a magic word that exposes public variables of a class to be visible in the Unity Inspector. This is imho an AWESOME feature which enables a tight integration between the code and Unity Engine GUI.
In this section he reminds us that to get to the scripting documentation when in Monodevelop is CMD+’ on the Mac.
There is a critical annotation here saying that we have to use “GetComponent” explicitly even though the code in this section doesn’t do so. This is addressed somewhat in the “Unity 5 Upgrade Guide” that is linked from the main tutorial page, however in that guide the code has a typo.
private Rigidbody rb;
Not a big change of course but the code won’t work without it.
It said to just click on ‘select’ and I could select a texture for my material but tut-rot strikes again and there was no select button. It gave me the apparently helpful hint that “Albedo” was what I was looking for but I don’t see a select button on that either!?! Referring back to the Unity5 Upgrade Guide I found nothing of value.
I tried dragging the texture onto the sphere at the bottom, and tried dragging it onto the Albedo field with no success. I also tried dragging the texture onto the material in the Project Browser but no luck. I jumped the gun a bit when I dragged the texture onto the VFX that we just made in the Heirarchy and it looked pretty good at that point, however that didn’t help with the point of this part of the tutorial: making a new material with an associated texture.
Eventually I figured it out! When looking at some of the documentation I noticed a texture in a place that I didn’t expect: I didn’t realize that the little check box to the left of the Albedo property is actually not a check box at all (I was wondering why it wasn’t checking when I clicked on it!?!) Instead it functions as the texture box and the even tinier icon to the right of that box brings up the select window. Having learned this lesson I will never have a problem with this again and will always see those “checkboxes” as “texture boxes and selectors”, but that was less than obvious and I don’t feel bad for not having seen that right off the bat.
The rest of this lesson went well and smooth.
This lesson discusses the difference between FixedUpdate() and Update() in scripts. Thats something that has been discussed before in these tutorials and basically the difference relates to whether physics are involved (FixedUpdate()) or not (Update()). It goes into quite a bit of detail about exactly what the code does (possibly TMI).
In the process of getting this working they show you how to create a constant stream of shots and although they don’t show this in the video its pretty fun to play with!
Note: I left gravity on my bolts on purpose to see what it would do 😀
I tried something here: I tried to make my shots veer to the right or left by adjusting velocity. It didn’t work so I asked my fiancé for a failure high five!
This section is about making your shot game objects delete themselves when they get outside of the play field. This is so we don’t make too terribly many game objects that never get deleted.
Before dinner today I took a stab at this and it totally worked!
However the way they are going to do it is more elegant and useful. They are making a boundary box into a trigger collider so they can test for objects to cross that boundary and therefore be destroyed. In one of the previous episodes I had left the gravity on the bolt, but at this point I removed it since the bolt was leaving the boundary box early (through the bottom actually).
This tutorial shows you how to make an asteroid. It talks about the Random.insideUnitSphere function which returns a random vector 3 value which we can use to set the angular velocity of the asteroid (making it rotate).
It talks about destroying the asteroid by programming some trigger collider interaction.
I liked the narration around 9m30s. He finds a bug, feigns surprise, and then says “No we aren’t standing at a flux point in the probability field. We have a bug.”
Making it Interesting (Explosions)
In this tutorial he shows us how to make the asteroid move, and explode which will effectively make it more interesting. It shows how to instantiate an explosion GameObject at the location and rotation of the asteroid which makes a pretty effective explosion effect imho. It instantly added a level of fun to the game and made me want to have more asteroids to blow up (which I’m pretty sure they are about to show us).
This tutorial also shows how to make the ship explode when it hits the asteroid. That is in fact a built in feature of the scripts as we have them written but I believe he is about to special case the ship explosion to make it more interesting (and so we can keep track of the score).
I noticed something: When you make a public class variable and don’t set it in unity, the execution effectively ends instantly. Example: I just added a playerExplosion public variable but didn’t set it and now my collisions don’t work anymore. It didn’t just not-instantiate the explosion that I didn’t set, it just gave up!
This video shows us how to create the game controller that will send the asteroids flying down at us like a digital-Zeus but with asteroids instead of lightning bolts.
In the process I did an experiment and moved my half developed “SpawnWaves” from Start() to Update(). I got this:
Interesting: Some are just disappearing. I don’t know why.
Waves of Hazards
This guy is claiming that one asteroid per game is too easy … ok he might be right. This video will spawn waves of them. In this video he is a bit judgmental about code he deems to be ugly … ok he might be right about that too. :p
In this section he spends a lot of time on a ‘for-loop’ which is a standard programming thing that imho he could have skipped over or referred to another resource, still he did a great job explaining it!
Wait! That is a legitimate problem
Problem: that problem in the “asteroids out of control” gif above (the one where the asteroids are deleting themselves for no reason) that is much more significant now that I’ve got fewer of them and its not happening in the video. This means I have a bug in my code somewhere and I have to debug it. I’m going to try to do that now before I go any further.
I put a line of code in the DestroyByBoundary class to show me when something exits the boundary and that seems to be the problem:
But why? I’m guessing that the asteroids have a vector in the y direction and are escaping out of the top or bottom.
I noticed that there is only a problem when the asteroids collide with one another so one way to fix it *seems* to be to make the asteroid prefab into a trigger collider because then its physics aren’t interacting with other asteroids physics, but I looked carefully through the videos and immediately prior to making the asteroid prefab the “Is Trigger” box is NOT checked so it doesn’t seem like thats how they solved it. I’m starting to think they didn’t solve it but if so I don’t know what I did differently.
Anyway the way I decided to fix it is to constrain the x and y values to 0.0f in the update routine of the mover like so
This worked and I can shoot the asteroids and all seems to be well now.
Back to Waves of Hazards
It talks about how to suspend a routine without suspending the entire game. The solution is to make that part into a C# coroutine and there are just a few specific pieces of syntax required to do this (a good example is the WaitForSeconds code example). The “StartCoroutine” and the return value of IEnumerator are really the only parts that matter. The StartCoroutine makes sense to me but I don’t know what an IEnumerator is or why its required and I don’t think that is explained well enough but regardless of all that otherwise it is just a normal routine but now has the ability to pause.
Well I had a problem right off the bat here: Audio wouldn’t play! Even just from the preview window. 90s of googling and I found the answer on a 2012 forum thread suggesting that on the Mac if this happens its usually because Unity3D has been open for a long time (true in my case: several days) and restarting Unity should re-enable sound. It totally worked.
There is a good explanation here of what 3D sound does and how it relates to an audiolistener.
The tutorial suggested that you could drag and drop a sound file into a prefab in the inspector and it would create an audio source automatically and populate it with that audio file. I tried for 5 minutes and did not find any way to make this work (dragging onto icons, browsers, inspectors, different parts of inspectors, etc.), so I just ended up doing it without the automatic drag and drop audio source that they spoke of in the video. Manually adding an audio source component and dragging the audio file into the first field (called ‘audio clip’) in that audio source component worked like a charm and I’ve got exploding asteroid sounds now!
The drag and drop did work when dragging onto the hierarchy and I was able to attach it to the player object this way.
In this section we are shown how to display a score and keep track of points as you accumulate them. The first thing they show is how to Create a GUI Text component but the way to do that in Unity5 17.1 is pretty different than the way they did it back in 2013 so there is a large annotation that pretty much says to do everything different.
An important note when making GUI text in Unity 3D 5 2017.1 has to do with the ALT key. (UPDATE: I realized a bit later that while this is technically correct and I’m glad I figured it out, this doesn’t apply directly to this tutorial since I had done something wrong. See the bottom of this section for details.)
If you click on the box in the top left of the Rect Transform component of the GUI text it seems like you can place the text wherever you want just by clicking. You have to hold down the ALT key to while you select to do that.
This video talks about GUI Text and its properties and limitations and how since its GUI we won’t see it in the Scene view.
Theres a bit of a naming problem when adding the score in since the parameter name is “newScoreValue” but we are just adding it to the current score value. It should probably be named something like “scoreToAdd”, but I understand not always getting things right because as we all know naming things is hard. To be fair to this tutorial I’ve been impressed with their naming throughout and have had only this single exception which is a pretty good track record imho.
In this video they do a good job of explaining objects and instances using a “valet parking” metaphor, which works quite well in this context. They do this while they are showing us how to do script to script messaging by identifying and then calling the games specific instance of GameController from within another script. Of all the code in this tutorial the code that finds the gameController instance makes me the least confident. Not because it wasn’t written well, but because there are so many places it could go just slightly wrong: finding the object by tag (what if there are two), getting the script out of the object, etc.
I encountered a problem near the end of the video: It said to drag the ScoreText object to the Score Text slot in the GameController inspector but that didn’t work. I suspect it has something to do with the type I selected in the code and am about to go check the Upgrade to Unity 5 Manual for clues.
Oh! When I re-read the instructions in the youtube annotation (the one that I screenshotted and pasted at the top of this section) I realized that I hadn’t done exactly what those instructions said to do. I did Create->UI->Text from the Hierarchy however it says to create an empty game object and add a GUI Text component. I’ll go do that (I bet it will work) … yup! It worked!
Success! Wow that ended up being a tough section for me.
Ending the Game
This video explains more about how the GUIText objects are positioned on the screen. Remember that 0,0 is the bottom left of the play window for these objects (see previous video). This video makes a public method that ends the game, and sets up the ability to restart by polling for the r key to be pressed in the update method.
This video speaks of using Application.LoadLevel() however the documentation shows that to be a deprecated method and suggests using SceneManager.LoadLevel() instead. Theres no Youtube Annotation for this so its good to know about it. It didn’t work immediately so I looked into the documentation and found out that it requires you to specify SceneManagement in the using list at the top of the file.
Deploying to the web
The hard part here has nothing to do with Unity. Its getting it uploaded to your web server! This section is straightforward.
My finished version is here in case you want to play it:
Thanks for walking through this adventure with me! The tutorial was more rotted than I imagined but also had a higher quality core than I first thought. Thanks to Unity for the engine and for the tutorial. What questions do you have for me?