Skip to content

Windmill – Creating a Complex Object Using Unity Primitives

Windmill - Creating a Complex Object Using Unity Primitives

By the end of this tutorial, you will be able to create and manipulate Unity primitive shapes, apply transformations, create a complex model and apply animations to the movable parts.

Contact me

You can find the entire source code of this project in the GitHub repo. https://github.com/shamim-akhtar/gamdev-unity.

View the Tutorial on YouTube

Introduction

In this tutorial, we will explore how we can create and manipulate primitive shapes in Unity to create a more complex model.

We will use Unity’s built-in primitive shapes to construct something more intricate: a complex model. What exactly do we mean by a “complex model”? 

Essentially, it is a brand-new 3D object obtained by piecing together various primitive shapes like cubes, cylinders, spheres, and more. Rather than starting from scratch with a single detailed model, we are leveraging Unity’s primitives to build something unique, layer by layer.

Picture it like assembling a puzzle. Instead of having all the pieces neatly cut into a single shape, we are working with a diverse set of building blocks, each with its own properties and dimensions. By combining these primitives strategically, we can create complex structures that wouldn’t be feasible to construct manually.

We do so by applying the model-to-world transformation to these individual primitives. This transformation allows us to manipulate the position, the rotation, and the scale of each primitive, effectively placing them within our scene and moulding them into the desired form.

Through this exercise, you will gain hands-on experience with Unity’s modelling capabilities, honing your skills in applying transformations to create complex 3D models.

Creating a Complex Model by Using Primitive Shapes in Unity

In this exercise, we create a Windmill, which is simple enough yet complex in the sense that it has multiple parts. This Windmill will have a base, a stand, a rotor, and blades attached to the rotor. We will then write a script to make the blades rotate at a certain RPM (or rotations per minute).

Create a new Unity 3D Project in a folder called UnityProjects in your local drive. If the folder does not exist, create it on your C drive or  D drive.  Name the project ProjectWindmill.

Right-click on the Hierarchy window and create an Empty Game Object. 

What is an Empty Game Object?

An Empty Game Object in Unity is a Game Object that serves as a container or placeholder within the scene hierarchy without any visible mesh or visual representation. It is essentially an invisible Game Object that can be used to organise other Game Objects, create hierarchies, or serve as a reference point within the scene. 

In our case, we will use an Empty Game Object to define the group that will hold all other Game Objects needed to create a Windmill. Rename this empty game object to Windmill.

Primitives in Unity

In the Unity Editor, you can work with 3D models of any shape created with modelling software. However, Unity also allows you to create several primitive or placeholder objects.

These are the cube, the sphere, the capsule, the cylinder, the plane and the quad.

  • Cube 

  

A white cube with six sides, each measuring 1 x 1 units. Commonly used for constructing walls, boxes, and as placeholders during development.​ 

  • Sphere 

  

A sphere with a diameter of one unit (0.5-unit radius). It is commonly used for representing balls, planets, and projectiles.​ 

  • Capsule 

  

The capsule primitive is a cylinder with hemispherical caps at each end. It’s typically one unit in diameter and two units high, with each cap being 0.5 units. Due to their rounded shape, capsules are great placeholders for prototypes, and they are more suitable for certain tasks than a box. 

  • Cylinder 

  

The default cylinder primitive in Unity is a tube that is two units high and one unit in diameter. Its texture wraps around the body once and repeats separately on both ends. Cylinders are handy for crafting posts, rods, and wheels. However, Unity lacks a primitive cylinder collider; instead, it uses capsules by default. For precise cylindrical physics colliders, you need to create a cylinder-shaped mesh in a modelling program and attach a mesh collider. 

  • Plane 

  

The default plane primitive in Unity is a flat square with edges measuring ten units, comprised of 200 triangles, and positioned in the xz plane of the local coordinate space. Its texture fills the square completely. Planes are versatile for creating flat surfaces like floors and walls, and they can display special effects, images, or movies in GUI. However, using a quad primitive might be simpler for these tasks. 

  • Quad 

The default quad primitive in Unity is a square with one-unit-long edges, divided into two triangles and positioned in the xy plane of the local coordinate space. Quads serve as screens for images or movies and are handy for creating simple GUI, information displays, particles, sprites, and imposter images for distant object representations. 

The Ground

Right-click on the scene Hierarchy window and create a Plane. Rename it to Ground. Ensure that the ground is at positions 0, 0, and 0 in the x, y, and z axes.

As a good practice, you should always reset the transform component of a game object after creating it to ensure that no unwanted offset is generated by Unity. To reset the transform, select the game object, find the Transform component in the Inspector, click on the three dots, and click reset.

The Windmill Base

Select the Windmill Game Object, right-click on it, and add a Cylinder Game Object. Select this Cylinder Game Object and rename it Base. We want the base to be flatter with a slightly larger radius. We can achieve this by applying scale transformation to it. 

To do so, go to the Inspector and change the Transform scale values to 3 on the x-axis, 0.2 on the y-axis and 3 on the z-axis. This means we are making the base 3 units in radius, similar to 3 metres, and 0.4 units in height, similar to 40 centimetres.  By keeping the x and z scale values as same, we ensure that the cylinder has a circular cross-section.

Change the position of the base to 0, 0.2 and 0 so that it does not sink into the ground.

The Stand

Select the Windmill Game Object. Right-click on it and create another cylinder. Rename it to Stand. Reset the transform first, as you should always do. Then, change the scale on the x and z axes to 0.5 and 0.5, respectively. Change the scale on y-axis to 10, effectively making it 0.5 metres in radius and 10 metres high.

Change the position to 0, 10 and 0 so that it does not sink into the ground.

With the current camera setting, you cannot view the entire structure. So, let’s adjust our camera so that we can view the entire object.

Adjust Camera

Select the MainCamera from the Hierarchy. Go to the Inspector and set the below values. You shall now be able to see the entire object in your Game view.

The Rotor

We will now create the rotor. Select the windmill game object, right-click it, and add a new empty game object. Set the position to 0, 20.25 and 0 in the x, y and z axis, respectively. Name this game object as Rotor.

Hierarchical Transformations

Now that you have created and manipulated a simple shape in Unity, let’s move on to understanding hierarchical transformations.

In Unity, a Transform component is an essential part of every Game Object in a scene. It defines the object’s position, rotation, and scale within the scene’s 3D space. Without a Transform component, a Game Object cannot exist or be properly positioned within the scene.

The Transform component stores and manages a game object’s spatial properties. Developers can access and modify these properties programmatically to move, rotate, or resize the object as needed during runtime. This allows for dynamic manipulation of Game Objects within the scene, facilitating animations, interactions, and other gameplay mechanics.

One of the key features of the Transform component is its ability to establish hierarchical relationships between Game Objects. By assigning a parent Game Object to another Game Object’s Transform, the child Game Object’s position, rotation, and scale are affected by its parent. 

This hierarchical structure enables complex transformations to be applied systematically, with child Game Objects inheriting and compounding the transformations of their parent Game Objects. This feature is particularly useful for creating complex scenes, organising game objects, and facilitating animations and character rigs.

Select the Rotor Game Object. Right-click on it and create a capsule. Rotate the capsule along x-axis by 90 degrees.

The Blades

We will now create the blades for our Windmill. To do so, select the Rotor game object and add a new empty game object. Rename it to Blade.

Select this blade game object and add a new cylinder. Resize it to 0.1, 0.25 and 0.1 in the x, y and z axes.

Rotate the cylinder by 90 degrees in the z-axis and set the position to 0.65 in the x-axis.

Once again, select this Blade game object and add a cube. 

Resize it to 7, 0.5 and 0.02 in the x, y and z axes, respectively. Set the position in the x-axis to 4.3.

Rename the Blade to Blade1. Duplicate this Blade1 two times. Rename the first duplicate to Blade2 and change the rotation to 120 degrees along the z-axis. Rename the second duplicate to Blade3 and change the rotation to 240 degrees.

We have established a fundamental windmill structure by utilising several empty game objects to outline the object hierarchy. By organising our objects in this hierarchy, we can effectively control the rotation of the rotor, thereby managing the movement of the blades appropriately.

To make the blades protrude out, we set the z position for all three blade empty game objects to 0.4. This is to ensure that the blades don’t go through the stand.

Scripting

We shall now create the necessary scripts to rotate the rotor. To do this, go to the project window and create a new folder called scripts.

Go to the scripts folder, right-click it, and create a new C# script. Name it Windmill. Attach this script to the Windmill game object by selecting the Windmill game object and dragging and dropping the script to the Inspector window.

Double-click the script and open it in Visual Studio.

Applying Rotation

Add a public variable of type Transform called the rotor. We shall attach the rotor from the inspector to this field.

public class Windmill : MonoBehaviour
{
    public Transform rotor;
    public float rpm1 = 10;
    public float rpm2 = 25;
    public float rpm3 = 50;

    private float rpm = 0.0f;
Code language: C# (cs)

Next, three float variables are added: rpm1, rpm2, and rpm3. These values will determine the rotor’s revolutions per minute. We will also add a private float variable called rpm, which will hold the windmill’s current active rpm.

We then add a new method called Rotate. This method is responsible for animating the rotation of the rotor of the windmill.

    void Rotate()
    {        
        float degreesPerSecond = rpm * 360 / 60.0f;
        float degreesPerFrame = degreesPerSecond * Time.deltaTime;

        rotor.Rotate(0.0f, 0.0f, degreesPerFrame);
    }
Code language: C# (cs)

Here, we calculate the rotational speed in degrees per second based on the desired RPM. It converts RPM into degrees per second by multiplying rpm by 360 and then dividing by 60.

After that, we calculate the degrees per frame by multiplying the rotational speed per second with Time.deltaTime. Time.deltaTime represents the time elapsed since the last frame, ensuring that the rotation amount is consistent regardless of frame rate.

Finally, we apply the calculated rotation increment to the rotor transform in its local z-axis.

Input Handling

We will now add some key bindings to change the RMP. We shall use the key A to set the rpm to rpm1, B to set the rpm to rpm2, C to set the rpm to rpm3 and D to set the rpm to 0.

To handle changing the rotor’s RPM based on keyboard input in Unity, we utilise Unity’s input system to detect specific key presses. The code checks for key presses using Input.GetKeyDown.

When the A key is pressed (represented by KeyCode.A), the Input.GetKeyDown function detects this key press. Upon detecting the key press, the rpm variable is set to rpm1. 

Similarly, when the B key is pressed, we set the rpm to rpm2, and when the C key is pressed, we set the rpm tp rpm3.

We also use the D key press to reset the rpm back to 0.


    // Update is called once per frame
    void Update()
    {
        // We shall use the keys A, B, C and D to toggle between
        // rpm1, rpm2, rpm3 and 0.
        if(Input.GetKeyDown(KeyCode.A))
        {
            rpm = rpm1;
        }
        if(Input.GetKeyDown(KeyCode.B))
        {
            rpm = rpm2;
        }
        if(Input.GetKeyDown(KeyCode.C))
        { 
            rpm = rpm3; 
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            rpm = 0;
        }

        Rotate();
    }
Code language: C# (cs)

Finally, we call the Rotate method to rotate the rotor.

Go to the Unity editor. Select the Windmill game object from the hierarchy. Drag and drop the Rotor game object to the rotor field of the Windmill script component. 

Click play. Press the A key to see the windmill rotating at rpm1. Press the B key to see the windmill rotating at rpm2. Press the C key to see the windmill rotating at rpm3. Press the D key to see the windmill stop rotating.

The stopping is abrupt, as we directly set the rpm to 0 and did not apply any physics to our objects. 

It’s important to note that this implementation lacks physics considerations, resulting in abrupt stops. While this method may not be ideal for windmill simulation, our focus was on creating a complex game object using primitive shapes in Unity, positioning these objects through transformations, and implementing scripts to enable rotation of the movable part.

Leave a Reply

Your email address will not be published. Required fields are marked *