Wednesday, January 23, 2019

Matrices Pt 1

A matrix is made up of a grid of real numbers, the grid can be r rows and c columns. If a matrix has 3 rows and 2 columns it is referred to as a 3x2 matrix. A matrix is typically expressed by a capital letter. These can be used to make changes or transform a vector or position in video games. There are two ways to declare a matrix

Method 1



Method 2



Identity Matrix
The identity matrix is a matrix with equal number of rows and columns to another matrix, as well as this each component of the identity matrix is 0, except for a diagonal of 1s that start in the top left and works its way down.



Addition & Subtraction
In order to add or subtract two matrices they have to have the same dimensions or in other words, the amount of rows must match and the amount of columns must match. When adding two matrices we simply add each corresponding component together.


The same goes for subtraction as we subtract each corresponding component from one another.


Matrix Equations
Matrix equations are equations where a matrix is being represented by a letter, similarly to how you might have the equation 5x = 15, which when solved gives x = 3.

An example of this is below, where we have to find A.


The first step is to get A on its own.


Then we carry out the matrix subtraction to give us the value of A.




Scalar Multiplication
This is the same as scalar multiplication of vectors as each component of the matrix is multiplied by the scalar value.



Zero Matrices
A zero matrix is a matrix which has ever element as a value of 0. A zero matrix is represented with a 0 like below and the dimensions are subscripted to that 0.


When you add a zero matrix to any matrix you get the original matrix, whereas if you add the opposite of a matrix to the original matrix you get the zero matrix. If you multiply a matrix by zero you get a zero matrix that has the same dimensions as the original.

All images were created using https://www.codecogs.com/latex/eqneditor.php

Linear Interpolation

Linear interpolation or lerp is used to calculate a linear value that is between two values, i.e. lerp could return a value of 0.5 as it's between 0 and 1, which were the two original values given to the function. So in this instance the value is 50% between the two original values.

Lerping can be applied to a wide range of values and not just real world numbers, such as colour, vectors and quaternions. These example are made up of multiple dimensions such as colour usually being made up of 3/4 floats that represent R, G, B and A), so no matter how many dimensions make up something, lerping can still be applied using the generic formula:

Lerp(_a,  _b, _f) = (1 - _f) * _a + (_f * _b)

Where _a and _b are the two points that are being interpolated between and _f is within the fractional range of [0, 1] in terms of _a and _b. It is also important to note that this formula is not frame rate independant and so by using deltaTime * _f will achieve that.

An example use of lerping is moving a platform from point A to point B, where each tick the platform's position is now a percentage between point A and point B using lerp. There are other variations on lerp such as slerp which is spherical lerping, that provide similar effects to lerping.

Friday, January 18, 2019

Unreal Engine - Blueprints Essential Concepts

What is a Blueprint?
A blueprint is a container for content as it can hold various components, scripts and data. It doesn't always need a script as it can be a data only blueprint. This means the designers can modify the data but not modify the behaviour of the blueprint.

Blueprints are a compiled object oriented visual scripting language and ties into the pre-exisiting UE4 framework class hierarchy. It is also completely embedded within UE4 and works by stringing together connections and nodes. You can also see the adjustments fairly quickly after the blueprint has been compiled.

There are two types of blueprints:
  • Level blueprint which is one per level and only affects that level
  • Class blueprint which can have multiple instances within a level and works in all levels
Blueprints are built on C++ and in fact when using blueprints you are using C++ as they can be even openned and edited in C++. This means both play nicely together.

Creating Blueprints
When creating a new blueprint, you can pick from a parent class which gives the new class some inherited functionality (hence why its object oriented). Most cases the parent class will be an actor, however, if there is a player controlled character or vehicle the parent class would be a pawn class.

Blueprints can be created from the content browser by clicking on the add new button or they can be created by placing various components within a scene, selecting said components, then converted to a blueprints class using the blueprint button in the upper middle section of the editor window.

The default scene root component is the base object which can affect its children components. This means if that root component moves, everything else moves with it. However, if you just move the child component, then the root component will stay still. You can also override the root component with another component by dragging the new root component on top of the default root component.

You can also add components or set meshes through the content browser by dragging it from the content browser to the blueprint window.

Blueprint Graphs
Construction script fire once at runtime and whenever a change is made in the editor. It can also be used for a variety of other features such as dynamically spawning in static meshes to randomly adjust how something might look. Such as a fence and the wooden planks that make up the fence, which could be spawning in different positions and rotations to create a variety of styled fences.

The event graph is the type of blueprint graph that will most likely to be used. In here we can program how the various objects work. So if we had a security camera we can use the Event Tick function (if this was Unity and C# this would be the Update function) to make the security camera move side to side, but then when the player moves within range it tracks the players movement and the security cameras light changes to red. To check if the player is within range we could use the Event Begin Overlap (if this was Unity, it would be the OnTriggerEnter function).

In the event graph we can create function graphs which can separate functionality and organise the event graph to be neater. This can be done by selecting a group of nodes, right clicking and selecting the collapse to function option. The advantage of creating a function is that it can be reused but also used and accessed within another blueprint.

You can also do the same but create macro graphs, which are similar to the functions graphs but don't require any input values. The macro graphs are more like utility functions and are accessible only in that blueprint unless a macro library is created and used. Like the function nodes, the macro nodes can be reused if needed.

You can also collapse nodes, which doesn't create a function graph or a macro graph but just helps tidy up the event graph and keeps things organise. It is important to note that these cannot be reused.

Types of blueprints
The level blueprint is used to create level specific functionality, this might be a useful for a shooting game where the player has x amount of time to escape the level before a bomb explodes as the levels before or after that one will most likely not require that functionality. The level blueprints also don't have access to the ability to add components or access the viewport like a class blueprint can.

Actor blueprints are modular blueprints that provide various functionality and can be reused throughout the level but also multiple levels. Unlike the level blueprint you can add various components to be used by the blueprint and access the viewport to move those components around if needed.

An animation blueprint is used to create the animation logic for various characters whether they are player controlled or not. A use for this is transitioning between idle, walking, jogging and running animations for the player based on the players movement speed. Unlike the actor blueprint, the animation blueprint also has another type of graph it can use. This graph is the anim graph, which can be used to set up state machines and animation transitions. The different between the anim graph and the event graph, is that the event graph controls the moment to moment variables whereas the anim graph controls the moment to moment final pose of the animation.

UMG (Unreal Motion Graphics) UI/ Widget graphs can be used to display and control a games user interface. An example of this is displaying the players health and energy bars, as well as updating them when the player takes damage or uses up stamina. It has an event graph which can provide the functionality of the UI elements. The designer tab is used to layout and add the various UI elements.

A child class inherits from a parent class, this allows us to use functionality from the parent class but also add some customisation based on the child class. An example of this would be item pickups. The parent class would have the functionality of what to do when the player hits the trigger volume but a child class would have extra functionality on top of that, so if it was a health pickup it would give the player more health where as an ammo pickup would give the player more ammo. To create a child blueprint, you go to the parent class you wish to use in the content browser and right click on it. At the top there should be an option to create a child class blueprint.

Blueprints Caveats

  • There is a cost associated with using blueprints over native C++ code
    • It is best to avoid doing complex maths or heavy operations every frame as blueprints use a virtual machine to translate the nodes into native C++ code
    • Native C++ is always going to be as it doesn't require translation via virtual machine
    • There is also some functionality that can only be performed using native C++ code and therefore that makes native C++ more powerful than blueprints
  • Blueprints is event based and therefore require specific events to trigger the various functionality programmed in those blueprints
  • Uses refererences and therefore possible to pass an invalid reference
  • It is also possible to create circular dependancies, this is where two or more blueprints depend on each other and so when one blueprint is casted to another the new blueprints dependancies are loaded, which links back to the original blueprint, whose dependancies also start to load. This then kickstarts the new blueprints dependancies again and so on.
NB. You can use casting during collision checks to see if an object is a certain type, this is similar to Unity's tag system as then you can provide specific functionality if the cast succeeds or fails.


Wednesday, January 16, 2019

Sample Problem: Rotating a 2D Character

The Problem
In a top down shooter, there is a scripted in game cutscene where an explosion happens and the player must turn to face the explosion. The turn to face the explosion must be a smoothed transition and since the cutscene can be triggered in a variety of ways, the initial direction of the player can be different between playthroughs. We need to know the angle the player needs to rotate and whether the direction they need to rotate is clockwise or anticlockwise.

The Variables
The current variables we have access to is the initial direction the player is facing (Vector C) , the position of the player (P) and the position of the explosion (E).

The Solution
The first step is to calculate the direction towards the explosion from the player, which can be done by subtracting P from E. This gives us Vector N and since we don't care about the distance between the two positions, we can normalise Vector N.

Since we now have two unit vectors (Vector N and Vector C), we can calculate the angle between them by using the dot product calculation. So the angle is equal to arccos(dotProduct(Vector C, Vector N)). However, this doesn't tell us if the direction we need to rotate is clockwise or anti clockwise.

This can be done with the cross product. However, since both vectors are in 2D space, they need to be converted into 3D vectors. Once the cross product is calculated we can determine the direction of the rotation needed. If the z component of the resultant vector is positive then the rotation is anti clockwise, which means if the z component is negative then the rotation is clockwise.

Cross Product

Using the cross product via two vectors, a third vector is calculated. There is a single plane that contains both vectors and so the third vector is the normal to that plane or perpendicular to the plane. Since the cross product returns a normal to a plane, it only works in 3D, however, it can work with 2D vectors after they have been converted into 3D vectors by adding a zeroed z component.

The formula for the cross product is simply Vector C = Vector A * Vector B
However, this gets extended to
Vector C = (Vector A.y * Vector B.z - Vector A.z * Vector B.y, Vector A.z * Vector B.x - Vector A.x * Vector B.z, Vector A.x * Vector B.y - Vector A.y * Vector B.x)

This can be hard to remember but there is a mnemonic that reminds you of the order for the subscipts for the x component of the cross product vector, which is "xyzzy". Combine this with the base equation of c = a*b - a*b and you have the first component.

Vector C.x = Vector A.y * Vector B.z - Vector A.z * Vector B.y

You can figure out the y and z components of the cross product vector by rotating the subscripts in the following manner: x -> y -> z -> x

Vector C.y = Vector A.z * Vector B.x - Vector A.x * Vector B.z
Vector C.z = Vector A.x * Vector B.y - Vector A.y * Vector B.x

It should also be noted that the cross product is anti commutatuve, so Vector A * Vector B = -Vector B * Vector A. Another note is that if the cross product returns a vector where all three components have a value of 0 then both input vectors are collinear, which means they lie on the same line. This means a plane cannot be formed and so there is no normal for the cross product to return.

Special Usage
Since a triangle is always on a single plane, we can calculate its normal by coverting two sides of the triange to vectors, then using those vectors and the cross product we can calculate the normal. If we only care about the direction and not the magnitude of the vector then we can normalise the vector afterwards.

Monday, January 14, 2019

Colour Theory

Colour can communicate emotions in a very primal way, however, due to different cultures, the symbolism of colours varies. There are constants that can be found in colour practice that help enhance the emotional messages of your designs.

A colour wheel has a primary function where the primary colours which are red, yellow and blue, sit opposite their complementary colours which are green, purple and orange. The colour wheel also has a function of displaying temperature, where it is split into half. The warm colours are between yellow to pink, whereas the cold colours are between green and purple. There are two dominate colours, the warm orange and the cold blue. Another function is a value scale, from lightest colour which is yellow to darked colour which is purple and any midrange value in between.

In theory, every colour in the spectrum can be mixed using just the three primary colours. Secondary colours are formed when mixing two primary colours together. For example, yellow and red create orange.

Complementary colours have a visual relationship where by placing each colour next to each other, the intensity of each colour increases. This allows you to attract the viewer's eye to important items, this is due the colours creating eye-catching contrast that can be likened to black against white.

Journey uses lots of warm colours that are close together on the colour wheel during the desert sections, this gives an emotional effect of harmony. However, in another part of the game, tension and unease is created by contrasting the orange and reds of the character with the complementary colours of green and blue from the envirnoment.

The colour of light must also be considered as well as the colour of objects. Light has different colour depending on the wavelength. The sun radiates warm colours such as red, orange and yellow, this makes objects seem warmer. However, if a cloud passes in from of the sun the blue light of the sky becomes a dominant light source, this causes objects to become cooler. So the dominant colour source dictates the temperature of colours within a scene. This is colour harmony, where an overall temperature unifies all the colours in an image.

Positioning colours also affects the temperatures as reds can seem cold next to blues and blues can seem warm against reds. So the combination of colours use depends on the overall light temperature in you scene.

Newtons Laws of Motion

Law 1
A body tends to remain at rest or continue to move in a straight line at a constant velocity unless acted upon by an external force.

Law 2
The acceleration of a body is proportional to the resultant force acting on the body, and this acceleration is in the same direction as the resultant force.

Law 3
For every force acting on a body there is an equal and opposite reacting force, where the reaction is collinear to the acting force.