Dana Vrajitoru
I355/C490/C590 3D Games Programming

I355/C490/C590 Lab 5 / Homework 5 Unity Version

Date: Wednesday, October 2, 2024. To be turned in by Wednesday, October 9. Here is a snapshot of the game:

In this lab, we will use the bee object created the last week and a height map to create a 3D application.

Lab Part

Ex. 1. In this lab we'll create an environment using a height map and implement a fly-through camera movement with it. The next week, we'll add the bee object to it.

Environment

Open Unity Hub and and create a new project called FlowerRun, of type 3D Core. Create folders Art, Scripts, Scenes, and Prefab in the Assets folder.

Rename the sample scene as WorldMap. Drag the height map image into the Art folder of your project.

Height Maps

There are online tools for generating height maps such as

https://terraining.ateliernonta.com/

Choose a location in the world to generate a height map, then save it as a png file and as a raw file. You can use that one or one from the following package (also containing textures):

lab5.zip

Create a new object in your scene of type 3D Object -> Terrain. Then in the Inspector, under Terrain, click on Terrain Settings. Scroll down to Terrain Resolutions and set a heightmap resolution to match your image. The map hMap1 is 612 x 612 and the others are 1025 x 1025. Then click Import Raw and choose the .raw version of the file you selected.

Leave the width and length as they are, but you can adjust the height of the terrain until it looks fine to you.

Camera
Move the terrain so that the middle of it is approximately aligned with the camera. Move the camera above the terrain, so that we can see it properly, and also rotate it a little towards the ground.

Terrain Texture

Drag the texture files from the zip file downloaded at the top into your Art folder in Unity.

Click on the Terrain object, then click the tab Paint Terrain (second from the left). From the top menu, select Paint Texture. Then scroll down to the Layers section. You will see Create New Layer at the bottom. Rename this GroundLayer and click Create. From the option that show up, select the ground texture (tan color) and double-click on it. This should both add the texture and apply it to the whole terrain. This is fine, it's our base texture.

Zoom in on one of the peaks in the editor. Add a new layer called SnowLayer and choose the snow image for it. Then change the brush size to something appropriate and paint the top of these peaks with snow. Repeat the procedure to add some grass to the scene where you think it would look good, as well as water if your map has any areas that look flat. Explore different brush shapes, sizes and strengths, and create a landscape that you like on your terrain.

Camera Movement

Zoom in on the camera. Add a script to the Main Camera object called CameraMovement. Add a public float variable called speed. Then go back to Unity and set its value as 20.

Add a rigid body to the camera to make the movement easier. Uncheck the use of gravity. Add the following variables at the top of the class:

Rigidbody rbody;

and initialize it in the function Start as

rbody = GetComponent<Rigidbody>();

Also add the functions vr, vy, vz like in Homework 2:

float vx()
{
    return rbody.velocity.x;
}

Then declare the following class variables:

public Vector3 forwardV = new Vector3(0, 0, 1);
public Vector3 rightV = new Vector3(1, 0, 0);

Open the Project Settings from the Edit menu and click on Input Manager. Expand the Axes section. The size at the top should show 18. Increase it by 1. At the bottom you will see that the last axis should show a duplicate of the previous one. Expand the last axis to edit it. Give it the name "Fly" and the descriptive names "Fly up" and "Plunge down". Enter "page down" into the Negative Button box and "page up" into the positive one.

Note that there is a duplicate for the Horizontal and Vertical axes. Edit the duplicates and enter "a" and "d" for the negative and positive buttons for the horizontal, and "s" and "w" for the vertical one.

Close the settings panel, then add the following function and make a call to it from Update:

void KeyMove()
{
    float horizontalInput = Input.GetAxis("Horizontal");
    float verticalInput = Input.GetAxis("Vertical");
    float flyInput = Input.GetAxis("Fly");

    Vector3 dir = forwardV * horizontalInput * speed + rightV * verticalInput * speed;
    rbody.velocity = new Vector3(dir.z, flyInput * speed, dir.x);
}

Now the camera should be moving forward and sideways with the arrow keys and WASD, as well as up and down using the PageUp and PageDown buttons.

We'll also turn the code for the mouse movement into a function.

Let's change the direction it is facing using the mouse. Declare the following class variables:

public float mouseSensitivity;
public float twistAngle, pitchAngle;

Set the value of the mouse sensitivity to 1 in Unity. Set the values of the two others in the function Start:

twistAngle = transform.rotation.eulerAngles.y;
pitchAngle = transform.rotation.eulerAngles.x;

Then add the following function to the class:

void MouseRotate()
{ 
    float mouseX = Input.GetAxis("Mouse X");
    float mouseY = Input.GetAxis("Mouse Y");
    if (mouseX != 0 || mouseY != 0)
    {
        float twistInput = -mouseX * mouseSensitivity;
        float pitchInput = -mouseY * mouseSensitivity;
        twistAngle += twistInput;
        pitchAngle += pitchInput;

        transform.rotation = Quaternion.Euler(0, 0, 0);
        transform.Rotate(0, twistAngle, 0);

        if (pitchAngle < -60)
            pitchAngle = -60;
        else if (pitchAngle > 180 && pitchAngle < 300)
            pitchAngle = -60;
        else if (pitchAngle > 60 && pitchAngle <= 180)
            pitchAngle = 60;
        transform.Rotate(pitchAngle, 0, 0);

        forwardV = Quaternion.Euler(0, -twistInput, 0) * forwardV;
        rightV = Quaternion.Euler(0, -twistInput, 0) * rightV;
    }
}

and make a call to it from Update if the mouse left button is down:

if (Input.GetMouseButton(0))
    MouseRotate();
Homework Part

Ex. 1. Decorations. Add some trees and flowers to the scene using the tree paint functionality of the terrain.

Ex. 2. Reset Button. Create a function

public void Reset()

that resets the camera to its original position. For this, declare 2 variables of type Vector3 and Quaternion respectively called initialPosition and initialRotation. In the function Start, assign to them the values of transform.position and transform.rotation respectively.

In the function Reset, assign the initialPosition back to transform.position and the same for the rotation.

Add a button to the scene with the text "Reset" that calls this function.

Create a Windows executable, create a zip of the folder, and add the script to it. Make sure that the zip file contains:

Homework Submission

Submit the zip file containing the Windows executable and the script file to Canvas, Assignments - Homework 5.