unity3d - computing systemsbranko-cirovic.appspot.com/cp3830/unity3d.basics.pdf · unity3d unity3d...
TRANSCRIPT
Unity3D
Unity3D is a powerful cross-platform 3D engine and a user friendly development environment.
If you didn’t like OpenGL, hopefully you’ll like this.
Remember the Rotating Earth? Look how it’s done with Unity3D.
Rotating EarthFire up Unity3D
Rotating EarthCreate new project (“Rotating Earth”):
Rotating EarthFrom the top menu add Game Object > 3D Object > Sphere
Rotating EarthWith sphere selected, change its scale to 8, 8, 8 in the Inspector:
Rotating Earth
Download earth.png and drag it from Finder into Assets folder at the bottom:
Rotating EarthNow, drag earth.png from Assets folder onto the sphere and release:
Observe that new subfolder Materials has been created with material earth in it:
Rotating EarthHit Play button on top:
Rotating Earth
Let’s change the background. From Hierarchy (upper left corner) select Main Camera.
In Inspector (upper right corner), change Clear Flags from Skybox to Solid color and change background to black (0, 0, 0)
Rotating EarthHit Play button on top:
Rotating EarthIn order to rotate earth about its own axis we need a script.
Select Sphere from Hierarchy and in Inspector Add Component > Scripts > New Script (rename to RotateEarth), Language C#
Observe that newly created script appears in Assets
RotateEarth.csDouble-click on script in Assets and MonoDevelop editor should appear.
Script comes with two empty methods:
void Start() which is used for variable initialization, and
void Update() which is called once per frame.
RotateEarth.csusing UnityEngine; using System.Collections;
public class RotateEarth : MonoBehaviour {
// Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.Rotate(Vector3.up, 20 * Time.deltaTime); } }
RotateEarth.cs
Function Rotate() takes two arguments:
Vector3.up - Specifies rotation axis (0, 1, 0)
Time.deltaTime - The time in seconds it took to complete the last frame (angle argument).
RotateEarth.csIf we wanted to rotate Earth about its axis AND about the origin (0, 1, 0) we need another function:
public void RotateAround(Vector3 point, Vector3 axis, float angle);
which rotates the transform about axis passing through point in world coordinates by angle degrees.
RotateEarth.csusing UnityEngine; using System.Collections;
public class RotateEarth : MonoBehaviour {
// Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.RotateAround (Vector3.zero, Vector3.up, 14 * Time.deltaTime); transform.Rotate(Vector3.up, 20 * Time.deltaTime); } }
RotateEarth.cs
If you play it now, there will be no difference, since both vectors coincide.
Translate Sphere along the z axis (z = 4) and run.
It’s alive!
Unity Interface
Inspector
SceneHierarchy
Project
Toolbar
Scene NavigationArrow Movement
The up and down arrows move the camera forward and backward in the direction it is facing.
The left and right arrows pan the view sideways.
Hold down the Shift key with an arrow to move faster.
Scene NavigationFocusing
If you select a GameObject in the hierarchy, then move the mouse over the scene view and press F, the view will move so as to center on the object.
This feature is referred to as ‘Frame Selected’ under the ‘Edit’ menu.
Scene Navigation
Move, Orbit and Zoom
When the hand tool is selected (shortcut: Q), the following mouse controls are available:
Move: Click-drag to drag the camera around.
Scene NavigationOrbit: Hold Alt and click-drag to orbit the camera around the current pivot point. This option is not available in 2D mode as the view is orthographic.
Zoom: Hold Alt and right click-drag to zoom the Scene View. On Mac you can also hold Control and click-drag instead.
Scene NavigationFlythrough Mode mode lets you navigate the Scene View by flying around in first person view.
Click and hold the right mouse button.
Use mouse and WASD keys to move left/right forward/backward and QE keys to move up and down.
Holding down Shift will make you move faster.
Primitive ObjectsUnity can work with 3D models of any shape that can be created with modelling software.
There are also a number of primitive object types that can be created directly within Unity, namely the Cube, Sphere, Capsule, Cylinder, Plane and Quad.
Any of the primitives can be added to the scene using the appropriate item on the GameObject > 3D Object menu.
Cube
This is a simple cube with sides one unit long, textured so that the image is repeated on each of the six faces.
Sphere
This is a sphere of unit diameter, textured so that the entire image wraps around once with the top and bottom “pinched” at the poles.
Capsule
A capsule is a cylinder with hemispherical caps at the ends. The object is one unit in diameter and two units high.
Cylinder
This is a simple cylinder which is two units high and one unit in diameter.
Plane
This is a flat square with edges ten units long oriented in the XZ plane of the local coordinate space.
Quad
The quad primitive resembles the plane but its edges are only one unit long and the surface is oriented in the XY plane.
Complex objectsThere are several different ways to include complex objects into the scene:
1. By importing objects from Unity Asset Store
2. By importing objects designed in some modelling software (Maya, Sketchup etc)
3. By using Probuilder
Probuilder Basic
MaterialsWe have already used materials in our Rotating Earth project.
They play an essential part in defining how our object is displayed.
CreatingMaterialsTo create a new Material, use Assets > Create > Material from the main menu or the Project View context menu.
By default, new materials are assigned the Standard Shader, with all map properties empty.
Using Materials
Once the Material has been created, you can apply it to an object and tweak all of its properties in the Inspector.
To apply it to an object, just drag it from the Project View to any object in the Scene or Hierarchy.
Material Properties
The properties that a Material’s inspector displays are determined by the Shader that the Material uses.
A shader is a specialised kind of graphical program that determines how texture and lighting information are combined to generate the pixels of the rendered object onscreen.
Material Properties
You can select which Shader you want any particular Material to use.
Simply expand the Shader drop-down in the Inspector, and choose your new Shader.
The Shader you choose will dictate the available properties to change.
Material Properties
The properties can be colors, sliders, textures, numbers, or vectors.
If you have applied the Material to an active object in the Scene, you will see your property changes applied to the object in real-time.
Material Properties
There are two ways to apply a Texture to a property.
1. Drag it from the Project View on top of the Texture square
2. Click the Select button, and choose the texture from the drop-down list that appears
Built-in Shaders
FX Lighting and glass effects
GUI and UI For user interface graphics
Mobile Simplified high-performance shader for mobile devices
Nature For trees and terrain
Particles Particle system effects
Built-in Shaders
Skybox For rendering background environments behind all geometry
Sprites For use with the 2D sprite system
Toon Cartoon-style rendering
Unlit For rendering that entirely bypasses all light & shadowing
Legacy The large collection of older shaders which were superseded by the Standard Shader
Lighting
Light source
Bright shading
Dark shading
In order to calculate the shading of a 3D object, Unity needs to know the intensity, direction and
color of the light.
These properties are provided by Light
objects in the scene.
Types of lightPoint Light is located at a point in space and sends light out in all directions equally.
Point LightUseful for simulating lamps and other local sources of light in a scene.
Types of LightSpot Light has a specified location and range over which the light falls off.
Spot LightSpot lights are generally used for artificial light sources such as flashlights
Types of LightDirectional Light represents large, distant source that comes from a position outside the range of the game world.
Direction only
Directional LightCan be used to simulate the sun or moon
Types of LightArea Light is defined by a rectangle in space. Light is emitted in all directions, but only from one side of the rectangle. The light falls off over a specified range.
range Can be used to create a realistic street light for example.
Using lightsGameObject > Light > Type
Shadows
Illuminated area
Shadow where light doesn’t reach the surface
ShadowsShadows for an individual light are set with the Shadow Type property.
Objects have properties Cast and Receive Shadows.
Cookies
Shadows can also be created by placing a shaped mask in between the light source and the action.
The mask is known as a cucoloris or cookie
A cookie is just an ordinary texture but only the alpha/transparency channel is relevant
CookiesSimple cookie for a window light
Imported into assets
Inspector settings Texture Type: Cookie
Cookies
In order to apply a cookie to a light, select light and drag it to the Light’s Cookie property in the inspector to apply it.
Cookies
Roll a BallCreate new Project
Scene
Save scene (File, Save Scene as or ⌘S)
Add Object to SceneAdd Plane to the scene (Game Object, 3D, Plane)
PositionIn Hierarchy select Plane and in Inspector, change its name to Ground
If the Ground is not positioned in the center of the coordinate system (0, 0, 0), reset it using “gear”
Scaling
Plane can be scaled either by selecting the “scale” icon and stretching the plane in X or Z direction
Or directly setting transformation scale coordinates in the Inspector (2, 1, 2)
More ObjectsAdd a player (Sphere from object menu) and rename it to Player. Observe that Sphere is “buried” in the plane.
Change PositionCenter of the sphere is in the centre of the coordinate system. In Inspector, set sphere’s Y position coordinate to 0.5
Materials and ColorsCreate new Folder under Project/Create. Rename it to Materials.
Materials and ColorsWith Materials folder selected, create Material. Rename “New Material” to Background.
Materials and ColorsWith Material selected, in Inspector, next to Albedo is the color selector. Set it to some color (e.g. 0, 32, 64)
Apply Material to ObjectTo apply material to an object, simply select material and drag into object (Ground in our case).
Change Light DirectionSelect Directional Light and using Inspector, change Rotation Y coordinate to 60
Rigid BodiesHow to move Player around the Ground?
This Requires Physics. Select Player (Sphere) and in Inspector, Add Component, Physics, Rigid body
Rigidbody
Rigidbodies enable GameObjects to act under the control of physics.
The Rigidbody can receive forces and torque to make objects move in a realistic way.
Rigidbody properties
The mass of the object (in kilograms by default).Mass
How much air resistance affects the object when moving from forces. 0 means no air resistance, and infinity makes the object stop moving immediately.
Drag
Rigidbody properties
How much air resistance affects the object when rotating from torque. 0 means no air resistance.
Angular Drag
If enabled, the object is affected by gravity.Use Gravity
Rigidbody properties
If enabled, the object will not be driven by the physics engine, and can only be manipulated by its Transform.
Is Kinematic
Try one of the options only if you are seeing jerkiness in your Rigidbody’s movement.
Interpolate
Rigidbody properties
Used to prevent fast moving objects from passing through other objects without detecting collisions.
Collision Detection
Restrictions on the Rigidbody’s motion.Constraints
Movement
Not much movement so far. In order to move Player around the Ground, we have to take and process inputs (Keyboard, Accelerometer etc).
And for that we need to write code. First of all create another folder called Scripts.
Movement
To create controller for our Player, select Player, Add Component, New Script. Name: PlayerController, Type: C-Sharp
You might have to move newly created script into Scripts folder
C# Script
If you select PlayerController script, you can see in the Inspector that some code has already been generated for us.
However, code is not editable in Inspector. Double-click PlayerController and start MonoDevelop (editor)
C# Scriptusing UnityEngine; using System.Collections;
public class PlayerController : MonoBehaviour {
// Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
C# Script
Start () method is called once in order to initialize variables. Which variables do we need?
Speed and reference to our player:
public float speed; private Rigidbody rb;
C# Script
Start () method initializes our Player :
void Start () { rb = GetComponent<Rigidbody> (); }
C# Script
Update () method is called once per frame and that’s where our animation goes.
For Desktop, Input are arrow keys and for phones, Input is Accelerometer by default.
What moves the Player is the force, which is the product of movement vector and the speed.
C# Scriptvoid Update () { float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rb.AddForce (movement * speed); }
Try to run it now (hit play button in Unity). Nothing happens. Why?
C# Script
What is the value of speed? Well, select Player and observe PlayerScript in Inspector:
Speed is 0 and so is the force. Set it to 10, run again and have fun!
It’s alive!
Camera
Our camera is static. How to have camera following our Player?
Select Main Camera and in Inspector lift it up (Y) and rotate by 45 degrees (X).
CameraTo control camera, we need a script. Select Main Camera, Add Component, New Script. Name: CameraController, Type: C-Sharp
The offset of type Vector3 is constant - difference between Player and Main Camera.
To update camera’s position we simply add player’s position and offset in Update () method ( or LateUpdate () as recommended)
CameraController.csusing UnityEngine; using System.Collections;
public class CameraController : MonoBehaviour { public GameObject player; private Vector3 offset; void Start () { offset = transform.position - player.transform.position; } void LateUpdate () { transform.position = player.transform.position + offset; } }
Camera
The last thing we need to do here is to assign Player to our CameraController.
Select Main Camera and drag Player into the Player field in Inspector.
Run and observe that camera follows player even if player falls of the edge of ground.
It’s alive!
WallsIt’s quite easy (and frustrating) for that ball to drop of the plain.
We are going to add walls by creating an empty game object Walls, resetting it and adding four walls to it.
To create a new Wall, add new 3D game object Cube, rename it to West Wall, reset and drop into parent Walls
WallsSelect West Wall and in inspector scale it to (0.5, 2, 20.5) and position to (-10, 0, 0)
Walls
To create the East Wall, select West Wall, Edit, Duplicate and change its position to (10, 0, 0)
Similarly, create North Wall - position: (0, 0, 10), rotation (0, 90, 0) and South Wall - position (0, 0, -10), rotation (0, 90, 0)
Walls
Collectable ObjectsCreate new Cube, rename it to Pickup and reset Transform.
Select Cube and Edit, Lock View to Selected. Player is in the way.
Select Player and in Inspector, deselect checkbox in front of the Player
Tranforms
Transform cube - position (0, 0.5, 0), rotation (45, 45, 45), scale (0.5, 0.5, 0.5)
We also want our Cube to permanently rotate - for that, we need a script.
Pickup selected, in Inspector add component, new script, C-Sharp, name: Rotator
Tranformsusing UnityEngine; using System.Collections;
public class Rotator : MonoBehaviour {
// Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.Rotate ( new Vector3 (15, 30, 45) * Time.deltaTime); } }
PrefabsLet’s create more pickup objects. In order to do so we will create Prefab (template for game object)
Start by selecting Project and create new folder Prefabs. Drag the Pickup object from Hierarchy into Prefabs folder
Also in Hierarchy, create an empty objectname Pickups and drag Pickup into it
PrefabsChange perspective to top (right click on gizmo)
Select Pickup from hierarchy and change its orientation from local to global
PrefabsNow duplicate (⌘D) and arrange Pickups
Materials again
Let’s change the color of our Pickups. In Assets, duplicate existing material (background) and in Albedo change its color.
Now simply drag newly created material into Prefabs/Pickup. Bingo!
It’s alive!
CollisionsIn order to pick up objects we have to detect when collision occurs between Player and Pickup
Open PlayerController.cs and add methodvoid OnTriggerEnter(Collider other)
void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag ("Pick Up")) { other.gameObject.SetActive (false); } }
CollisionsFor this code to work we need to associate tag “Pick Up” with our Pickup prefab.
Select Pickup from Prefabs and in Inspector, Tag select Add Tag
In the dialog, add tag, name: Pick Up
CollisionsBack in Inspector, prefab Pickup select, choose Pick Up tag. Observe that the same tag is associated with all pickup objects.
If we run the game now, there is not much difference - Player still bounces agains Pickups.
Select Pickup from Prefabs and in Inspector, Box Collider, check Is Trigger checkbox.
Physics OptimizationCalculating collisions with rotating cubes (static cache) per each frame can be computationally expensive.
The solution is to add rigid body to our Pickup objects.
Select Pickup from Prefabs, Add Component, Physics, Ridid Body.
This will turn static coliders into dynamic coliders.
Physics OptimizationRun.
Oops! All Pickups drop trough the floor (gravity pulls them down. They are triggers and do not collide with the floor)
One might be tempted to disable gravity in Rigidbody component
Physics Optimization
This would work in our example, but not in general, since rigid body would still react to physics forces.
The solution is to declare Pickup as Kinematic - now it won’t react to physics forces.
Display Text (Score)
In order to keep track of the score we need to enhance our PlayerController.
Select Scripts, PlayerController. To keep track of picked up cube we’ll declare:
private int count;
And set it to zero in our Start () method.
Display Text (Score)
Count is incremented in our OnTriggerEnter method:
void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag ("Pick Up")) { other.gameObject.SetActive (false); count++; } }
Display Text (Score)
To display count, we’ll need to use Unity’s UI Tool Set.
From Hierarchy, CreateUI Text
Display Text (Score)
Observe that Unity also created Text’s parent object Canvas as EventSystem game object.
All UI elements must be children of the Canvas element.
Rename Text to Count Text and in Inspector change its color to white, reset position.
Display Text (Score)We’ll position our text into the upper left corner of the screen using Rect transform Anchor Presets
Shift + Alt presents more options.
Padding and size can be changed in Pos X, Pos Y, Pos X, Width, Height fields of Rect transform
Display Text (Score)
To wire up UI Text to display count value, open PlayerController script.
At the top of the script we need to declare namespace:
using UnityEngine.UI;
Display Text (Score)
Next we declare reference to our UI Text component:
countText.text = "Count: " + count.ToString ();
public Text countText;
And initialize it in Start () method:
Display Text (Score)Same code is executed in OnTriggerEvent () method after counter is incremented.
Finally, in Unity editor, select Player and observe that Count Text field has been created.
From Hierarchy, drag and drop Count Text into None (Text) field.
Display Text (Score)Run.
Game OverLet’s create another UI Text (name: Win Text, color: white, position: center top)
As before, in PlayerController.cs,declare Text variable
public Text winText;
Initialize it to an empty string:countText.text = "";
Game OverAfter counter is incremented, see if it’s 12 - total number of pickup objects.
if(count >= 12) winText.text = "You win!";
Back in Unity editor, select Player and drag and drop Win Text from Hierarchy into Win Text placeholder.
Build and RunFrom the main menu,
select File,Build Settings
Give it a name
Build and Run