unity3d - computing systemsbranko-cirovic.appspot.com/cp3830/unity3d.basics.pdf · unity3d unity3d...

Post on 28-Jul-2018

306 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

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

top related