Clock

Create a new Unity Project

In the hierarchy create an empty game object to hold the components of our clock.

Rename the game object and ensure that the scale is uniform and position and rotation are zeroed out.

Create the clock face

Add a Cylinder object to our Clock object. Ensure that it's transform values are the same as those for the clock.

Turn the cylinder into a clock face by flattening the Y scale and make the face bigger by increasing the X and Y scale.

We want the clock to be upright as if hanging on a wall.

In Unity the X axis points right, the Y axis points up, and the Z axis points forward.

Set the cylinder's X rotation to 90 and adjust the scene view so the clock's front is visible, so the blue Z arrow of the move tool points away from you, into the screen.

Change the name of the cylinder game object to Face, as it is one component of the clock, it is a child of the clock.

We need to create the hour positions on the clock.

A clock is a circle which has 360 degrees.

There are 12 hour positions. 

Therefore 360 divided by 12 gives us 30 degrees. 

30 degrees between each hour position.

Add a cube object to the scene, name it Hour Indicator 12, 

and also make it a child of Clock.

Set its X scale to 0.5, Y scale to 1, and Z scale to 0.1 so it becomes a narrow flat long block. Then set its X position to 0, Y position to 4, and Z position to −0.25. That places it on top of the face to indicate hour 12. Also remove its BoxCollider component.

Create a new material for the 12th hour indicator. 

Change the Albedo.

Add the material to the hour indicator.

Albedo is a Latin word which means whiteness. It's the color of something when illuminated by white light.

We need an indicator for every hour but we will start with the cardinal points.

Begin by orienting the scene view camera so we look straight down the Z axis. You can do this by clicking on the axis cones of the view camera gizmo at the top right of the scene view. You can also change the axis of the scene grid to Z via the grid toolbar button.

Duplicate the Hour Indicator 12 object. 

Rename it to Hour Indicator 6. 

Now Negate it's Y position.

Do the same for indicators 3 and 9 

Their X positions should be 4 and -4 with 0 Ys.

 Also their Z rotation should be 90 degrees.

Then create another duplicate of Hour Indicator 12, this time for hour 1. 

Set its X position to 2, its Y position to 3.464, and its Z rotation to −30. 

Then duplicate that one for hour 2, swap its X and Y positions, and double its Z rotation to −60.

How are the positions calculated?

Duplicate these two indicators and negate their Y positions and their rotations to create the indicators for hours 4 and 5. 

Then use the same trick on hours 1, 2, 4, and 5 to create the remaining indicators, this time negating their X positions and again their rotations.

Creating the Arms

To create the hour hand duplicate hour indicator 12 and rename it to Hours Arm. 

Create a Clock Arm material, I chose solid black, use it on the arm.

Decrease the arms X scale to 0.3

Increase the arms Y scale to 2.5

Change the Y position to 0.75 so that it points up to 12 but is offset slightly downwards.

ROTATION

The arm needs to rotate around the CENTER of the clock

PROBLEM: If we change its Z rotation the arm rotates around its own center!

SOLUTION: Create a PIVOT object and rotate that instead.

Create an empty game object

Make it a child of Clock

Name the object Hours Arm Pivot

Ensure its position and roation is 0 and its scale is 1

Make Hours Arm a child of the Pivot

Duplicate Hours Arm Pivot twice to create a Minutes Arm Pivot and a Seconds Arm Pivot. Rename them accordingly, including the duplicated arm child objects.

Minutes Arm should be narrower and longer than Hours Arm

set its X scale to 0.2 and Y scale to 4, then increase its Y position to 1. 

Change its Z position to −0.35 so it sits on top of the hours arm. 

Note that this is for the arm, not its pivot!

Adjust Seconds Arm as well. 

This time use 0.1 and 5 for the XY scale 

and 1.25 and −0.45 for the YZ position.

The seconds arm should stand out.

Make a different material for it using a bright colour.

Animating the clock

Add a new script asset to the project via Assets / Create / C# Script and name it Clock.


Open the Clock Script in your code editor by double clicking it.


Delete all code in the Clock Script.

An empty file defines nothing. It must contain the definition of our clock component. 

We define the general class or type known as Clock. 

Once that's established, we could create multiple such components in Unity, even though we'll limit ourselves to a single clock in this tutorial.

In C#, we define the Clock type by first stating that we're defining a class, followed by its name.

Because we don't want to restrict which code has access to our Clock type, it is good form to prefix it with the public access modifier.

At this point we don't have valid C# syntax yet. If you were to save the file and go back to the Unity editor then compilation errors will get logged in its console window.

We indicated that we're defining a type, so we must actually implement it. That's done by a block of code that follows the declaration. The boundaries of a code block are indicated with curly brackets. We're leaving it empty for now, so just write {}.

Our code is now valid. Save the file and switch back to Unity. 

The Unity editor will detect that the script asset has changed and triggers a recompilation. 

After that is done, select our script. 

The inspector will inform us that the asset does not contain a MonoBehaviour script.

What this means is that we cannot use this script to create components in Unity. 

At this point, our Clock defines a basic C# object type. 

Our custom component type must extend Unity's MonoBehaviour type, inheriting its data and functionality.

What does mono-behavior mean?

The idea is that we can program our own components to add custom behavior to game objects. That's what the behavior part refers to. 

The mono part refers to the way in which support for custom code was added to Unity.

 It used the Mono project, which is a multi-platform implementation of the .NET framework. 

Hence, MonoBehaviour. It's an old name that we're stuck with due to backwards-compatibility.

We must make Clock into a subtype of MonoBehaviour. 

Change the type declaration so that it extends that type, which is done with a colon after our type name, followed by what it extends. 

This makes Clock inherit everything of the MonoBehaviour class type.

However, this will result in an error after compilation. 

The compiler cannot find the MonoBehaviour type. 

This happens because the type is contained in a namespace, which is UnityEngine. 

To access it, we have to use its fully-qualified name, UnityEngine.MonoBehaviour.

It is inconvenient to always have to include the UnityEngine prefix when accessing Unity types. Fortunately we can declare that the namespace should be searched automatically to complete type names in the C# file. 

This is done by adding using UnityEngine; at the top of the file. 

The semicolon is required to mark the end of the statement.

Now add the custom component to the Clock game object in Unity. 

This can be done either by dragging the script asset onto the object, 

or via the Add Component button at the bottom of the object's inspector.

To rotate the arms, Clock objects need to know about them. 

Start with the hours arm. 

Like all game objects, it can be rotated by adjusting its Transform component. 

So we have to add knowledge of the arm pivot's Transform component to Clock. 

This can be done by adding a data field inside its code block.

Defined as a name followed by a semicolon.


The name, hours pivot would be appropriate for the field. However, names have to be single words.

 The convention is to make the first word of a field name lowercase and capitalize all other words, then stick them together. 

Name it hoursPivot.

We also have to declare the type of the field, which in this case is UnityEngine.Transform. 

It has to be written in front of the field's name.

Our class now defines a field that can hold a reference to another object, whose type has to be Transform. 

We have to make sure that it holds a reference to the Transform component of the hours arm pivot.


Fields are private by default, which means that they can only be accessed by the code belonging to Clock. 

But the class doesn't know about our Unity scene, so there's no direct way to associate the field with the correct object. 

We can change that by declaring the field as serializable. 

This means that it should be included in the scene's data when Unity saves the scene, which it does by putting all data in a sequence—serializing it—and writing it to a file.


Marking a field as serializable is done by attaching an attribute to it, in this case SerializeField. 

It's written in front of the field declaration between square brackets, typically on the line above it but can also be placed on the same line.

Once the field is serializable Unity will detect this

 and display it in the inspector window of the Clock. 

To make the proper connection, drag the Hours Arm Pivot from the hierarchy onto the Hours Pivot field. Alternatively, use the circular button at the right of the field and search for the pivot in the list. 

In both cases the Unity editor grabs the Transform component of Hours Arm Pivot and puts a reference to it in our field.

Accessing all three arms

Add two more serializable Transform fields to Clock with appropriate names.

Because these fields are all the same data type, we can make this code much shorter:

Now connect the other two arms in the editor.

Moving the arms

We will rotate the arms as the components awaken. We will do this in the Awake method.

Methods are somewhat like mathematical functions, for example:

That function takes a number—represented by the variable parameter x —doubles it, then adds three. 

It operates on a single number, and its result is a single number as well. 

In the case of a method, it's more like

where p represents input parameters and c represents whatever code it executes.

Like a mathematical function a method can produce a result, but this isn't required. 

We have to declare the type of the result—as if it were a field—or write void to indicate that there is no result. 

In our case, we just want to execute some code without providing a resulting value, so we use void.

We also don't need any input data. 

However, we still have to define the method's parameters, as a comma-separated list between round brackets. 

It's just an empty list in our case.

We now have a valid method, although it doesn't do anything yet. 

Just like Unity detected our fields, it also detects this Awake method. 

When a component has an Awake method, Unity will invoke that method on the component when it awakens.

 This happens after it's been created or loaded while in play mode. 

We're currently in edit mode, so this doesn't happen yet.

To rotate the arms we have to create a new rotation. 

We can change the rotation of a Transform by assigning a new one to its localRotation property.

Although the rotation of a Transform component is defined with Euler angles in degrees per axis in the inspector, in code we have to do it with a quaternion.

We can create a quaternion based on Euler angles by invoking the Quaternion.Euler method. 

Do this by writing it in Awake, followed by a semicolon to end the statement.

The method has parameters used to describe the desired rotation. 

In this case we'll provide a comma-separated list of containing three arguments, all between round brackets, after the method name. 

We supply three numbers for the X, Y, and Z rotations. 

Use zero for the first two and −30 for the Z rotation.

If you enter play mode now 

you will see that the clock is set to 1pm.

Getting the current time.

We can use the DateTime struct to access the system time of the device we're running on. 

DateTime isn't a Unity type, it is found in the System namespace. 

It is part of the core functionality of the .NET framework, which is what Unity uses to support scripting.

DateTime has a Now property that produces a DateTime value containing the current system date and time. 

To check whether it's correct we'll log it to the console at the start of Awake. 

We can do that by passing it to the Debug.Log method.

Now we get a timestamp logged each time we enter play mode. 

You can see it both in the console window and in the status bar at the bottom of the editor window.