Week 3

homework

What if the snitches were moving?

Put a script on the snitch that gives it a little push
slow turn car
    public float speed;
	private Rigidbody rb; 

	void Start ()
	{
		rb = GetComponent ();
		rb.AddRelativeForce(0, 0, speed, ForceMode.Impulse); 
	}
 
To keep the snitch from slowing down put an extremely bouncy physics material on it and set the drag and angular drag to 0.

Make it turn like a car (only when moving)

My idea to solve this was to get the total speed of the car. Getting the total value of a vector is called getting the "magnitude". The velocity is a vector3 that will tell you how fast it's moving in the x y and z axis. So if we get teh magnitude of the velocity it will tell us if the car is moving.
moving a snitch
	private float locX = 0.0f;
	public float speed;
	private Rigidbody rb;

	void Start ()
	{
		rb = GetComponent ();
	}
	void FixedUpdate ()
	{
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");
		Vector3 movement = new Vector3 (moveVertical, 0.0f, 0);
		rb.AddForce(transform.forward * moveVertical * speed); 
		float actualSpeed  = rb.velocity.magnitude; 
		if (actualSpeed > 0.1) {
			transform.Rotate (0.0f, moveHorizontal * actualSpeed, 0.0f);
		}
	}
 

UI elements

Now that we have a game we need to display the score.
Putting text on the screen, either as an element in the space or as a floating HUD (heads Up Display) requires a Canvas and a text element. The easiest way to make this is to go under the GameObject menu to UI to Text - notice that doing this also automatically creates a parent Canvas element.

The default for the canvas is as an overlay, which is what we want, so lets leave that alone. You won't see anything in Scene view, but switch to game view and you should be able to see the sample text.

odd button

The text gameObject has a rectTransform instead of a regular transform area, and in it there's a janky button that allows you to reset where the center origin point is. Why you don't just change the X and Y values I don't know but whatever, it's there so might as well use it, eh?

coding for the UI

Here's the hardest part of coding the text - remembering to add UnityEngine.UI at the top the code.
UnityEngine.UI
Now make a public Text variable. (Don't forget to drag your text gameobject from the hierarchy into the space in the inspector before you test the game)
public Text scoreText;
The next code should go into the start, and once after the collision has occurred.
scoreText.text = "Score: " + score.ToString();
Unlike Processing the text will stay on the canvas even if we are not continually drawing it in a loop
Collision plus score: put on player object
	using System.Collections;
	using System.Collections.Generic;
	using UnityEngine;
	using UnityEngine.UI;
	
	public class snitchCollision : MonoBehaviour
	{
		public int score;
		public Text scoreText;
	
		void onStart ()
		{
			score = 0; 
			scoreText.text = "Score: " + score.ToString(); 
		}
			
		void OnTriggerEnter (Collider col)
		{
			if (col.gameObject.tag == "prize") {
				Destroy (col.transform.parent.gameObject);
				score++; 
				scoreText.text = "Score: " + score.ToString(); 
			}
		}
	}
 

Rotation: a mathematical horror story

Gimbal Lock

Here's the truth about rotation, it's not as simple as you've been lead you to believe. This is because of something called "Gimbel Lock". The good thing about gimbal lock is that it's fun to say, the bad thing is it's confusing at first to get your head around, but the other good thing is it's not as confusing as you think, but the bad thing is the solution to gimbal lock is REALLY confusing but the good thing is we can avoid most of that because computers do it for us, but the bad thing is this sentence - seriously, get a grip.
If you think about rotation in space you have 3 angles, x,y,z. These angle are often called Pitch Roll and Yaw. Gimbal Lock happens when one of those angles lines up with another angle. When that happens you're not literally "locked" but you can now only move in two directions.
gimbal lock on Apollo

gimbal lock example.

Quaternions

The solution in the real world is adding a 4th gimbal, and that's the solution in mathematics as well. So even though intuitively you'd think you can rotate to any direction with 3 numbers (often called Euler Numbers (pronounced "Oiler")), because of gimbal Lock you actually need to use 4. This system of rotation is called Quaternions which is also fun to say, and sounds both nerdy and impressive. But imagine how cool it sounds when British people say it!

So what does this mean to us? In the transform there's an x y and z for rotation but Unity actually uses Quaternions under the hood.
So if you try to just set the rotation of an object with
transform.rotation = new Vector3(0, 130, 0); // this won't work!
You'll get the error message. "Cannot implicitly convert type `UnityEngine.Vector3' to `UnityEngine.Quaternion'" There is an easy way, however, convert from Euler angles to Quaternions with
transform.rotation = Quaternion.Euler(0, 130, 0);
"Hey", you're saying, "last week we used transform.Rotate(0.0f, moveHorizontal * speed, 0.0f); That has three variable and it works fine, what gives?" Great Question!
The answer lies in the fact that "Rotate" and "rotation" are not the same thing. Rotate is a verb so the object will continuously rotate a specifically amount around a given axis. Rotate automatically converts the amount into Quaternions for us under the hood. Rotation is a fixed amount, but it's in Quaternions so it's expecting a Quaternion variable not a Vector3. "Hey", you're saying, "why not just just use Quaternions and learn how to rotate with four values?" - you go ahead and do that.
camera made with primitives

Practical Application of Quaternions

Let's make a box that sits on the side of the arena on a post. Have the "lens" pointing on the z axis (forward). First make a new script for the box create a public GameObject called "player" that you will attach the player object too in the inspector.
In update, add this code,
Quaternion rot = player.transform.rotation;
transform.rotation = rot;
This will make the camera rotate the same way we are rotated. But what if we want it to point at us, for that there's "lookAt"
transform.LookAt(player.transform);
Another useful term is Quaternion.identity. This the same as the fixed world rotation, or if it's applied to a child, the same as the parent. You can use it to reset the rotation of an object.
transform.rotation = Quaternion.identity;

Skybox and finding Assets

skybox image
While we're making it look pretty, lets add a skybox. If you click on the assets tab you can find free skyboxes there. Download one of them into your project. To activate the skybox, go under window to lighting. I usually dock the lighting window in the same area as the inspector. Go to the scene tab and you'll see an area for the skybox. Either drag from the project folder or use the circle to open a dialog box.
Problem: the skybox only shows up when you play the game, but you want to see it in the scene. Solution: make sure you are in scene mode. Directly above the scene window are buttons for affecting the scene. One of these lets you toggle the skybox on or off.
What's more fun is you can make your own skybox! Here's how to do it our of photo-shop. Photoshop skybox tutorial The key points are the original file size is 8192 x 6144 and the subsequent squares are 2048. Also, remember that Unity swaps the left and right.
Tutorial for making a skybox from 360 or panorama
If you're really interested, take a look at Terragen. They have student licenses.

Instantiating a Prefab

Guns in video games are ubiquitous and boring. Let's get it out of our system. First make a gun nozzle that is a child of the ship. Next make a bullet sphere, name it and make it a prefab.
Select the nozzle and go GameObject create empty child. (As you age, you'll find the term "create empty child" gets more and more cathartic.) Move the empty child out front of the gun nozzle a little bit (okay, that's a little grizzly even for me, sorry. Let's call it a "paint gun") - this will be the location that paint balls spawn.
Create a script that attaches to the empty child. This script will do five things for us.
  1. check to see if the space-bar is pressed
  2. put an instance of a bullet prefab at the location of the empty child
  3. make sure it's an actual GAmeObject
  4. set the rotation so it's facing the right direction.
  5. give it a little push.
Instantiate and move a prefab
	public GameObject bullet; 
	public int bulletSpeed = 10; 

	void Update () {
		if (Input.GetKeyDown("space")){
			GameObject BulletObject = (GameObject) Instantiate(bullet, transform.position, Quaternion.identity); 
			Rigidbody rb = BulletObject.GetComponent<Rigidbody>(); 
			rb.AddForce(transform.forward * bulletSpeed, ForceMode.Impulse);
		}
	}
Every bullet you create is going to be something that the computer has to think about, so writing something that deletes the bullet over time is useful. This code would go onto the bullet itself.
Kill the bullet over time
	public float timeLeft = 2.0f;
	void Update()
	{
		timeLeft -= Time.deltaTime;
		if (timeLeft < 0)
		{
			Destroy(gameObject);
		}
	}
Okay, what about collision? Write something that detects if a bullet has hit a snitch or the player.
The following might be necessary at some point to reset all the bullets at once. It puts every bullet in an array, then destroys them all. It's kinda bad assed actually.
Kill all the bullets at once
    GameObject [] x = GameObject.FindGameObjectsWithTag("bullet");
    foreach (GameObject i in x)
    {
        Destroy(i); 
    }

Assets

Assets are awesome and awful. They let you do a lot but can keep you from learning. We will use assets sparingly especially at first, but for some things they are just too super handy to ignore. In this case we will use assets to create a simple landscape and to implement a more robust camera
Go to the assets window and select "Standard Assets" (you want the one that does NOT say it's for Unity 4.6). You can import them all if you want, but for now to keep the download smaller and your project folder less complicated you can select these assets only.
  1. • Characters
  2. • CrossPlatformInput
  3. • Editor
  4. • Environment
  5. • Utility
When you import them they will automatically go into your project folder. With the install in the lab we should have the standard assets already installed. Look under the Assets menu to see if what you need is there. Ask Felicity if you need help
maya interface

Maya Intro

Maya is awesome and huge and really simple. Two of those things are true.
Things that are different than other software you might be used to.
  1. Even some of the menus on the top of the screen are "context aware" and depend on the mode you are in. The first File Edit Create Select Modify and Windows will always be there but the ones that follow will depend on the "menu set" that you are currently in.
  2. Maya navigation uses "hotboxes". These are menus that pop up on top of the scene you're working on. press and hold the space bar to access a bunch of menu items easily. Left click with the space pressed to get some quick navigation items.
quickly tapping the space bar toggles the quad view and single view
If you right-press the mouse you get a hotbox menu for switching between "object" mode and "various editing modes" Good new! We are only using Maya to make models that will work in Unity. That means we can ignore a lot of the program that goes into making high-realism renders like cameras and lighting because we're going to be exporting for Unity anyways!

moving around the view-port in Maya

This is not the same as Unity. They do this on purpose because they hate you. Trick - In Maya, put your finger on the command key. This is your world into finding the right way to navigate.

Change the units

In Unity the base unit "unity Units" but it is really 1 meter. If we make Maya the same then going between them is easier and we're not scaling as much.
Go: Windows > setting preferences > Preferences. On the left select Settings, and set the working Units to Meters. You can also get to the preferences by clicking on the icon in the lower right of a little orange man being chased by a white gear.

Make simple Polygon object

Make sure you are in the "Modeling" menu set and make sure you have the "poly modeling" tab selected. Click on a cube primitive to put a cube in the space.

Where is everything?

channebox icon
Coming from Unity some things are similar - the tools should look familiar and the 3d primitives. One thing you might wonder is "where's the inspector?" The Inspector in Maya is called the Channel Box and the icon for it is in the top right corner of the screen. It looks like a stack of paper.
The icon next to the Channel box is the Tool Settings. This is a where you can modify the regular tools. Double clicking a tool also brings up this box. The hierarchy equivalent is called the Outliner. You find it by going Windows - Outliner. To be honest, you won't need it as much as you do in Unity.
A poly model in 3D is made up of vertex (points), lines (connecting points) and faces. select the cube and right-click in the space. Select "vertex" from the hotkey menu and click on one of the cube's point. You can distort the cube by moving the point in space. You can do the same for faces and lines.
add divisions menu

Select the cube and go Edit Mesh - Add Divisions but let go on the square on the right. This will open up window that is the way into the finer details of how a menu item works. You can subdivide your cube, but be careful more lines = more complexity.

modeling with boolean

Create another Object and intersect the two so they are touching. Right click and use the hotkey to make sure you are in object mode - then select both objects.
Go: Mesh>Boolean>Union
Make another basic shape and overlap it. Select one shape and then shift-click to select the other - notice that the fist selection turns white and the second one is green.
Go: Mesh>Boolean>difference
Boolean difference takes the second selected shape from the first. (The green selection get taken from the white.) Mesh>Boolean>Union will combine.
When you have something groovy looking, save your model.

Extrude

Last modeling trick for now. Edit Mesh - Extrude (or command - e) let's you pull out faces. If you're used to Sketchup this tool is familiar. With faces selected and the extrude tool in use, go under Modify - Transformation Tool - show manipulator tool (or just press 't'). This brings up a dialog box where you can toggle "keep faces together".
extruding faces of sphere

Simple textures

The texture or materials window in Maya is called "hyperShade" like were stuck in a bad 80's cyberpunk movie. Deal with it ... to the MAX!
hypershade icon
The icon for the hypershade window looks a little like an olive. Yum.
In the "create" window pick "Lambert". There is probably some clever way to remember "Lambert" but I can't think of what that could be. Name your new color and make it not gray. Move the window so you can see your model and select some faces. Center click and drag the new color onto the selected faces of your model. If you don't select faces first it will color your entire model object. As long as the model has different materials you can change them in Unity.

Exporting from Maya

There are some standards in 3D but there are always new ones. Technically Unity can open Maya files directly, but I like to save files as an "fbx" file just to be sure.

Importing Into Unity

Go to unity and drag your saved model into the project folder. Drag onto the to see it in the context of your other stuff aaaaaaaaand .... Shoot - it's not big enough. Dang. Try playing the game and it just falls through the ground plane. Double bummer.

Fixing scale the best way

It's tempting to scale it with the scale tool, and if you're 100% sure it's the only time you're using the model that's probably fine but there's a better way to scale it without resizing it in unity that doesn't involve going back to Maya.
Click on the model in the project folder. The inspector should show the model with some tabs. Make sure the "Model" tab is selected. Now change the scale from here. Notice that the "Apply" button at the bottom of the inspector lights up. Click it.

fixing collisions the best way

For most shapes you will want to create simple colliders, but for complicated shapes you'll need a mesh collider. Mesh colliders are "expensive" on the CPU, so you want to use them sparingly. Click on the model in the project folder again and in the inspector click the "generate colliders" check-box. If you look inside your model now you'll see that the components of your model has a mesh collider on it. You cannot easily have a mesh collider collide with another mesh collider.

terrain

Create a new terrain (GameObject - 3D Object - Terrain). Check out how to use the Terrain tools in the manual and make a landscape with hills, trees, grass and wind.

virtual oudoor scene

Walking around

Find the "FPSController" prefab in your project folder using the search bar, and drag it into your scene. This prefab has a camera attached already, so you should delete the original camera. This camera controller has a lot of parts to it, but the biggest is a script that moves with wasd, and a script that looks with the mouse. It's pretty robust. try playing and moving around.
Note: if the controller is rotating on the z axis in a weird way stop the game and make sure that the x and y rotation of the FPScontroller are set to 0.