General information regarding programming assignments will be posted here.
Programming Assignment 2:
Sample Executable:
For a sample executable of the assignment Click here. Hit space to change the view. Use the mouse to change direction, w key to go forward.
Programming Assignment 1:
Sample Executable:
For a sample executable of the full assignment click here. Note that the "Quit" button on the menu screen does not work, because it is not possible to terminate a WebGL program. A stand-alone version of the program should terminate when "Quit" is hit.
Menu Tutorial:
A quick tutorial for building a main menu can be found here. (We did not need to use "Text Mesh Pro" in our implementation, but you are certainly welcome to use it.)
Explosions can be generated using Unity's particle-system object. There are a number of tutorials on making explosions, and you are free to use anything you like. We followed the approach mentioned here. We imported a particle system from the Unity standard assets (Assets → Import Package → Particle Systems). We selected "ExplosionMobile" (Standard Assets → Particle Systems → Prefabs → ExplosionMobile.prefab). We made a few additional modifications. For example, it consists of three separate elements, "TrailsWhite", "Sparks", and "Fireball". We deleted the TrailsWhite element, but kept the other two.
How to Shoot Bullets:
There are various ways to shoot stuff in Unity. Some methods are based on ray-gun type weapons, which use raycasting to determine what is hit. The other is projectile-based, where a bullet object is generated, and you use collision events to determine what is hit.
The basic method for handling a projectile-based shooting operation is was described in a Unity tutorial Merry Fragmas. That's no longer on Unity's site, but the videos remain on YouTube: Unity Tutorial on Single-Player Shooter. Quoting from the web page (with my own additions):
Create a new Sphere primitive GameObject. (We went further and duplicated it 5 times spread out in a line, so that each shot generates a little "burst". This is optional. We made them all children of an empty game object called "Burst". We also colored them green, since they are recyclable! Finally, we added a capsule collider to the Burst object to enclose the bullets.)
Rename the Sphere GameObject "Bullet" (or whatever you like)
With the Bullet GameObject selected:
Change the scale of the GameObject's Transform to (0.2, 0.2, 0.2). (Ours were even smaller.)
Find and add the component: Physics → Rigidbody. (But in our case, we attached it to the parent object, Burst.)
(One more thing we did was to assign the Bullet/Burst object a tag, say "Bullet", which will be used below.)
On the Rigidbody component, set the "Use Gravity" checkbox to false. (Since Bullets fly straight.)
Drag the Bullet GameObject into the Project Window to make a prefab asset. (And put it within a subfolder called Resources...this is where Unity looks when loading prefabs.)
Delete the Bullet GameObject from the scene. (It will be dynamically generated from the prefab whenever you fire.)
Save the scene.
Continue to follow the instructions, but with the following modifications:
The main elements of the shooting behavior are given in function Fire. It instantiates a bullet object at the bullet spawn position. It gives it an initial velocity of 6. (You can choose whatever you like. We did 10.)
There is no need to create the cylinder for the gun barrel, but you can if you like. Just set up the Bullet Spawn position to be attached to the front of the player, so that its forward vector (Z) is pointing in the same direction the player is pointing.
The tutorial does not explain how to process hits, but the idea is to create a handler OnTriggerEnter in your pickup controller script (assuming that pickups have the "isTrigger" option selected). Check whether the object's tag is "Bullet". If so, then we need to instantiate the explosion and destroy or deactivate ourself.
How to get the player to hover above the ground?
In Part 2 you need gravity, but the player will just fall onto the ground. The trick is to provide it with a collider that extends below the player cube. The downward motion stops when the collider hits the ground, and so the player appears to be hovering just above the ground. In the Unity editor, the Cube's box collider has its own Center and Size. You can adjust these to obtain the desired result.
Moving the player around (smoothly and crisply):
My own thinking about how to do this went through many changes over time. You want the player to be affected by physics forces in order for gravity to work, but using forces to move the player is difficult (since you need to give it a hard kick to get it to move quickly and a large drag or friction to get it to stop quickly). Even though the Unity manual recommends against directly setting the velocity of non-kinematic objects, I found (after some experimentation) that this yields the simplest solution. The trick is that you want to separate vertical motion (along Y), which is controlled by physics and horizontal motion (along X and Z).
Here is an approach that works pretty well. Let's just consider the front-back motion, but this works for rotation as well. First, get the user input in your Update function (e.g., using Input.GetAxis). Then convert this into a scalar value, let's call it thrust. This will be positive for forward motion and negative for backward motion. Let rb be a variable that stores a reference to the player's rigidbody component (using GetComponent). Now, just set the velocity directly: rb.velocity = transform.forward * thrust + transform.up * rb.velocity.y. The forward-backward component of motion is set according to thrust (ignoring physics), and the vertical component (Y) is simply a copy of its current value (which is determined by the gravitational physics). For rotation, you change rb.angularVelocity instead.
I tried that, and now my player doesn't rotate:
The problem is that the player is still affected by friction. The lack (or slowness) of rotation is due to friction between the player's collider and floor. There is an easy fix, however. In your Project window, create a new Physic Material, called "Mister Slippery" (well, call it what you want). Set its static and dynamic friction values to 0. Then attach Mister Slippery to your player collider, ground colliders, and anything else your player may scrape against.
How to get the Pickups moving up and down?
An easy way to get the pickup objects to move up and down is to set their vertical (Y) coordinate according a sinusoidal function of time. In Unity, the system variable Time.time indicates the elapsed time since the start of the game. So, intuitively we would like to do something like transform.position.y = verticalOffset + Mathf.sin(Time.time), for some desired verticalOffset value (to lift it high enough above the ground).
Unfortunately, this not quite what we want. First, Unity does not allow you to alter just a single coordinate of transform.position. You need to assign it an entire Vector3. This is easy (if a bit tedious): just make a copy the current position as a Vector3, change its y-coordinate, and then copy it back. Second, all your pickups will oscillate in unison. To add a bit of randomness, we can alter the speed with which it alternates, call this oscillationSpeed, and apply an offset to the time value, to move it to a random position within the period. So, the above expression would become something like verticalOffset + Mathf.sin(oscillationSpeed * (Time.time + timeOffset)). You can use Unity's Random.Range function to set the speed and time offsets randomly. Adjust the oscillation speed so that game is challenging, but not too difficult.
The easy way to get the camera to follow the player:
A number of you came up with clever techniques for computing the camera's position so that it follows the player, and we applaud your mathematical skills! But, there is a much simpler method. Just make the Main Camera a child of the Player (by dragging the Main Camera over the Player object in your hierarchy). Now, wherever the Player goes, the Main Camera will follow. There is a cute trick for positioning the Camera in Unity. Go to the scene window and position the view so that you see the world from exactly the perspective you want your Main Camera to have. Then select your Main Camera object and select GameObject → Align With View. This aligns the Main Camera with the current view.