Adding the Date

I began the week by implementing a date, as a UI TextMeshPro element, that would increase as the player spent longer in space. As there is currently no backdrop, there is no specific point where the player reaches space, however, I arbitrarily set it at Y = 50. This means that when the rocket’s y coordinate is 50, or above, the code knows that they are in space and, as such, will increase the year incrementally.

To get the year to increase incrementally, rather than going rapidly and in time with the FPS of the game, I added a clock that counts to 100. Only when the clock reaches 100 will it increase the year; after this the clock resets to 0, so that it can count to 100 again.

I also implemented functionality for the year to start in BCE. I did this by adding a boolean variable, called ce, and if it is true then the code will know that it is in CE and it will add 1 to the year variable. If ce is false, the code knows that it is in BCE and will instead take 1 away from the year variable; this is until it reaches 0. When the year variable reaches 0, ce is set to true for the rest of the run. I programmed the year to start at 1000, which is translated to 1000 BCE as ce always starts as false, but this value may change with playtesting.

Refining Movement

Next I refined the player’s movement, as it felt very floaty and did not react fast enough to player interaction. This was especially prevalent when the player accelerated upwards and let go, so that the rocket would go down; however, it would take a while for the force of gravity to overcome the upwards force that had been building up as the player accelerated upwards, and sometimes this would take up to 10 seconds for the rocket to even start falling back down. You can see some evidence of this in the video for week 1.

To fix this problem, I began by increasing the force of gravity on the rocket. This made the movement slightly better, when I increased the strength of gravity only a little, but at high gravity strengths the rocket suddenly felt very heavy and bulky; this resulted in much slower and more meaningful movements that did not fit with the arcade style of the game. In the end, I left the gravity at 1.2 strength, which is slightly higher than before.

I also added a script that, if the player was not interacting with the game and therefore the rocket should be falling, reduced the velocity a small amount each frame; this only applied if the velocity was already positive. Essentially this is like slamming on breaks which, for a spaceship, would be thrusters firing from the opposite direction of the movement; in the case of the rocket this could be seen as thrusters firing from the top of the rocket and pushing it down. If I have time, I would like to add art assets for these. Doing this made the game much more responsive to player interaction.

Asteroids

I implemented the asteroids by using an infinite spawner at the right side, off of the screen. I created a prefabricated GameObject as the asteroid, which the spawner would instantiate copies of on both sides of the rocket. The prefab asteroid automatically moved horizontally by a fixed amount each frame; this amount was determined in a setup function that I created, to determine whether it would move left or right.

I created a setUp function to essentially act as a constructor for the GameObject, whenever the prefab was instantiated by the spawner to generate a new asteroid, so that I could establish variables like the direction of movement for the asteroid, before the update function would be called. This is because instantiating an object only clones an already existing object, rather than making a new one, therefore a constructor would not be needed.

In the setUp function, I needed the asteroid to quickly establish 3 things before it even moved. These are the direction it will move in, along with the initial side it will spawn on, and a y position offset in relation to the rocket. To do this, I made the spawner, which is position just offscreen, to randomly choose a string from an array which has 2 options: “left” or “right”. The spawner also randomly chooses an offset, from a range of -6 to 14. If the offset is negative then the asteroid will spawn below the rocket. These two variables are then passed into the setUp function, immediately after the object is instantiated. The code for the spawner, called every frame, can be seen below:

void Update()
    {
        if (clock > spawnRate) /* To stop the asteroids from spawning rapidly, every frame, a clock
                                * is used to count to a specified number before a new asteroid is
                                * spawned
                                */
        {
            clock = 0; // The clock is reset to 0 whenever an asteroid is about to be spawned

            int i = random.Next(0, 2); // Randomly chooses a number between 0 and 1, to use as an index
                                       // when choosing a direction
            string direction = directions[i]; // Uses the index number to get a direction from the directions array
                                              // The directions available are "left" or "right"

            int offset = random.Next(-6, 15); // Randomly chooses an offset value

            GameObject newAsteroid = Instantiate(asteroid, transform.position, transform.rotation); /* Instantiates the asteroid
                    * When instatiating the asteroid, the spawner's current position is passed to it so that the asteroid
                    * spawns in the same place (offscreen to the right, inline with the rocket)
                    */

            AsteroidMove newAsteroidScript = newAsteroid.GetComponent<AsteroidMove>(); // Gets the move script for the asteroid
                                                                                       // so that its setUp function can be called

            newAsteroidScript.setUp(direction, offset); // Calls the setUp function for the asteroid and passes the direction
                                                        // and offset variables, which are established above
        } else
        {
            clock += 1; // Increase the clock count, if an asteroid is not being spawned in this update
        }
    }

The code in the setUp function takes the 2 parameters, direction and offset, and uses them to place the asteroid where it needs to be, as well as making it move in the right direction. First, it uses the direction parameter to determine whether it should stay in its current x position (on the right side of the rocket) or invert it (to start on the left of the rocket); the offset is also added on here, to make the asteroid start in the correct y position. Lastly, it determines whether the moveVector, which is added to the asteroid’s position every frame, will be a left or right vector. The code can be found below.

public void setUp(string direction, int offset)
    {
        // If the direction is set to "left", then the asteroid will need to move left and start at the right
        if (direction == "left") 
        {
            // Change the position by adding the offset to the y position
            transform.position = new Vector3(transform.position.x, transform.position.y + offset);
            // Set the moveVector to a vector moving left, multiplied by the specified speed
            moveVector = Vector3.left * speed;
        }
        // If the direction is set to "right", then the asteroid will need to move right and start at the left
        else if (direction == "right")
        {
            // Invert the x position of this asteroid and add the offset to the y position
            transform.position = new Vector3(transform.position.x * -1f, transform.position.y + offset);
            // Set the moveVector to a vector moving right, multiplied by the specified speed
            moveVector = Vector3.right * speed;
        }
    }

I also programmed the asteroids to destroy themselves once they reached a certain distance along the x axis.

Implementing Death

To implement the player dying, I needed to program the game to restart whenever the player collided with an asteroid. I began by adding a circle collider to the asteroids which allowed the rocket to collide with them. Initially, I did not have these set to be triggers and they, therefore, affected the rocket’s rigidbody; this allowed them to push the rocket around, resulting in the following:

The asteroids also spawn very close to the player here, as I was still configuring the spawner and wanted the asteroids to spawn onscreen, where I could see them

The asteroids also spawn very close to the player here, as I was still configuring the spawner and wanted the asteroids to spawn onscreen, where I could see them

I fixed this by setting the asteroids to triggers, which can still register collisions without affecting rigidbodies. Next I added to the rocket script and implemented a function that called whenever the rocket collided with something. I used a switch/case statement that checks the tag on the object to determine what was collided with, allowing me to easily implement other collisions - like fuel - later, and added the case for asteroids. I then programmed the game to return to the start menu if they have collided with an asteroid. Here is the code: