Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... ·...

28
Unity and Vector3, Quaternion, classes, structs, and instances Assistant professor in computer games Perttu Hämäläinen

Transcript of Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... ·...

Page 1: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Unity and Vector3, Quaternion,

classes, structs, and instances

Assistant professor in computer games

Perttu Hämäläinen

Page 2: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector3 • A collection of three numbers: x,y,z.

• Can represent place, displacement, velocity – anything

with a 3d direction and magnitude

• Vector2 is the same, but with just x,y

• Vector1 = scalar, just a single number

(0,0)

Vector2 a = new Vector2(5,5);

(5,0)

(0,5)

y

x

Page 3: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector scaling (multiplication with scalar)

• Scalar multiplication only affects magnitude, not

direction

0,0

Vector2 a = new Vector2(3,1);

Vector2 b = a * 3;

or alternatively,

Vector2 b = a;

b.Scale(3);

Page 4: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector scaling example

• Make an object move forward 5 m/s

rigidbody.velocity = transform.forward * 5.0f;

• transform.forward is a unit vector (of magnitude 1.0),

points along the game object’s z axis. This gives us the

direction. To get the velocity vector, we scale the

direction appropriately.

Page 5: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector addition

0,0

Vector2 a = new Vector2(3,1);

Vector2 b = new Vector2(1,3);

Vector2 c = a + b;

Page 6: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector addition

0,0

Vector2 a = new Vector2(3,1);

Vector2 b = new Vector2(1,3);

Vector2 c = a - b;

• Remember that a – b = a + (-1.0 * b)

Page 7: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector addition and scaling example

• Translate an object without a rigidbody with a constant speed

independent of game frame rate. Code in Update()

transform.position += transform.forward * speed

* Time.deltaTime;

• transform.position and transform.forward are both Vector3

• transform.forward * speed is the velocity vector

• need to scale with Time.deltaTime to make motion

independent of game fps

Page 8: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Scaling the moved distance based on

Time.deltaTime

• Object moves at constant speed -> travelled distance

grows linearly as a function of time

distance

time (seconds)

distance per frame at 10 fps, deltaTime = 1/10

1.0 2.0

distance per frame at 1 fps,

deltaTime = 1

Page 9: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Vector addition and scaling example 2

• Place a camera behind and above this gameobject,

looking at this gameobject

camera.transform.position = gameObject.transform.position

- gameObject.transform.forward * 2.0f

+ Vector3.up * 2.0f;

camera.transform.LookAt(gameObject.transform.position);

• Vector3.up is a constant, equal to new Vector3(0,1,0).

Note that using uppercase Vector3 denotes the struct or

class instead of a specific instance (see next slide...)

• The transform.LookAt() method rotates the object so

that it’s z-axis (transform.forward) points at the target

Page 10: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• Related to how things are stored in computer memory

Memory:

Scale()

0,1,0

1,0,0

...

...

...

...

...

...

...

...

...

...

Vector3 (code, static

and const)

//Vector3 definition (C#)

struct Vector3

{

//global (static, const) data

void Scale(float scale)

{

...

}

static Vector3 up=new Vector3(0,1,0);

const Vector3 right=new Vector3(1,0,0);

//member variables

float x,y,z;

};

unused (free) memory

Page 11: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances • The new operator allocates instances in memory

• Class/struct data stored only once, member variables for each instance

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

...

...

...

...

...

...

...

Vector3

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

a (instance data)

b (instance data)

Page 12: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• Important! Vector3 is a struct (a value type). For

structs, a new instance is allocated and members copied

when assigning Vector3 c=b;

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

3,2,1

...

...

...

...

...

...

...

Vector3 struct data

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

a

b

c

Page 13: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• In this case, changing c doesn’t change b

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

10,2,1

...

...

...

...

...

...

...

Vector3 struct data

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

c.x=10; a

b

c

Page 14: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• If Vector3 was not a struct, but a class like GameObject,

only a reference would be allocated when assigning (=)

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

983241

...

...

...

...

...

...

...

Vector3

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

a

b

c (reference to b)

Page 15: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• To be more precise, the memory would look like this...

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

983241

983242

983242

...

...

...

...

...

Vector3

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

Vector 3 instance

Vector 3 instance

a (reference)

b (reference)

c (reference, equal to b)

Page 16: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• In this case, changing member variables of c changes b.

The references c and b denote the same object.

Memory:

Scale()

0,1,0

1,0,0

1,2,3

10,2,1

983241

...

...

...

...

...

...

...

Vector3 class data

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

c.x=10;

a

b

c (reference to b)

Page 17: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• Remember the difference, otherwise you’ll encounter

strange bugs

Memory:

Scale()

0,1,0

1,0,0

1,2,3

10,2,1

983241

...

...

...

...

...

...

...

Vector3 class data

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=b;

c.x=10;

a

b

c (reference to b)

Page 18: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Classes, structs and instances

• However, we can make a copy by allocating a new

object and explicitly copying the data.

Memory:

Scale()

0,1,0

1,0,0

1,2,3

3,2,1

10,2,1

...

...

...

...

...

...

...

Vector3 class data

Vector3 a=new Vector3(1,2,3);

Vector3 b=new Vector3(3,2,1);

Vector3 c=new Vector3(b);

c.x=10;

a

b

c

Page 19: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Memory allocation and performance

issues

• You should avoid using new in FixedUpdate() or

Update() because otherwise you will get occasional

framerate drops because of memory allocation problems

(heap fragmentation, garbage collection).

• However, using new for structs doesn’t cause fps

glitches, because structs are allocated from stack

memory instead of heap, which is faster

Page 20: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Javascript and value types

class Vector3 extends System.ValueType

{

var x:float;

var y:float;

var z:float;

}

Page 21: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Quaternion = rotation

• Fast and intuitive use of Vector3 etc. requires

repetition.

Page 22: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Quaternion = rotation

• Fast and intuitive use of Vector3 etc. requires

repetition.

• Explaining how things like vector math work helps in

learning, but with enough repetition, we can learn, e.g.,

new verbs and grammar based on context only

Page 23: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Quaternion = rotation

• Fast and intuitive use of Vector3 etc. requires

repetition.

• Explaining how things like vector math work helps in

learning, but with enough repetition, we can learn, e.g.,

new verbs and grammar based on context only

• A quaternion is a mathematical tool for operating with

rotations. It’s a collection (in Unity, a struct) of 4

numbers: x,y,z,w.

Page 24: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Quaternion = rotation

• Fast and intuitive use of Vector3 etc. requires

repetition.

• Explaining how things like vector math work helps in

learning, but with enough repetition, we can learn, e.g.,

new verbs and grammar based on context only

• A quaternion is a mathematical tool for operating with

rotations. It’s a collection (in Unity, a struct) of 4

numbers: x,y,z,w.

• Quaternion math is difficult to understand, but using

Unity quaternions is fairly easy

Page 25: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Why quaternion instead of Euler angles

• 3d modeling packages, including Unity Inspector view,

let users manipulate rotation using Euler angles (rotation

around x, y and z angles)

• Internally, there’s some computational problems (gimbal

lock) -> most software use quaternions

• Unity allows you to convert between eulers and

quaternions

Page 26: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Quaternion examples

//rotate v (Vector3) 90 degrees around y axis using Eulers

v *= Quaternion.Euler(0,90,0)

//rotate v (Vector3) 90 degrees around a given axis (here Vector3.up)

v *= Quaternion.AngleAxis(90,Vector3.up)

//Rotate head partially to the direction of a target.

//In reality, we follow partly using eyes, partly by turning our head.

//Here, we limit the head turning to 45 degrees, assuming that we start

//from a neutral rotation. Slerp (spherical linear interpolation) returns

//a rotation that is between the given two rotations

Vector3 headToTarget = targetPosition – headTransform.Position;

Quaternion fullRotation = Quaternion.LookRotation(headToTarget);

Quaternion partialRotation = Quaternion.Slerp(headTransform.rotation,

fullRotation,0.5f);

headTransform.rotation = Quaternion.RotateTowards(headTransform.rotation,

partialRotation,45);

• Vector3 is rotated by multiplying it with a Quaternion.

Page 27: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

About radians and degrees

• Some Unity rotation helpers assume that given angles

are in radians. 360 degrees = 2π radians

• π is in Unity Mathf.PI

• 0 radians = 0 degrees.

• 0.5π radians = 90 degrees

• π radians = 180 degrees

Page 28: Unity and Vector3, Quaternion, classes, structs, and instancesphamalainen/unity_intro... · Quaternion examples //rotate v (Vector3) 90 degrees around y axis using Eulers v *= Quaternion.Euler(0,90,0)

Summary

• Vector3 and Vector2 scaling and adding/subtracting

often needed

• Quaternion provides rotation utilities – need to know

how to use, don’t need to know the numbers inside.

• structs (value types) allocated from stack -> use when

possible, new Vector3() doesn’t have an additional cost

• Remember that for classes (reference types),

assignment only copies a reference