Game Project: Flying Game: Sonic Boost – Part 4 – Projectile and Environment Interaction

June 2, 2021

Flying Game

Projectile


Overview

I was trying to think of ideas on how to add an extra mechanic to the flying controller that ties in with a fast and agile moving controller, and thought of tying in some type of sonic boom effect. With this, I thought creating an expanding projectile from the player after boosting could be an interesting way to generate these projectiles. I then explored a few ways to have the projectile interact with the environment and came across a relatively simple one that provides some fun feedback.

Sonic Boom Projectile

Everything about the projectile is rather simple. The projectile is generated when the player performs a fully charged boost. It then expands at some growth rate (dictated by the projectile controller on the player) up until some maximum size (dictated in the same location). As it encounters objects with an IDestructible interface, it will cause them to perform their Destroyed() method.

This gives a pretty cool effect that at least has a minimal basis in real world physics. It also makes tight turns and effective direction changes tied to a boost more satisfying when performed properly. It does have a major flaw currently however in that a majority of the action is normally happening behind the player, so they do not get to witness it most of the time. This is a pretty severe drawback that I will need to investigate some solutions to.

Voxelized Environment Obstacles

I initially liked the idea of creating targets or obstacles that could be destroyed by this growing sonic boom that would deteriorate as the sonic boom moved into it, as opposed to a more general game approach where contact would just do damage and destroys the entire object as a whole. This led me to making a bit more voxelized targets, which were made up of several chunks instead of just being a single large mesh.

To begin, I created a Voxel Obstacle script which is the overall container of a full obstacle made of several voxelized elements. This script just holds 3 dimensional values and builds out a solid cube/rectangular solid based on those dimensions.

The elements that make up the full obstacles are just simple prefab cubes for now, with a VoxelObstacleElement script. That script implements the IDestructible interface just so they have a Destroyed() method for the projectile to interact with.

Initially I had these elements have their gameobjects destroyed on impact with the projectile just to test the interactions. This was an ok approach, and gave the deteriorating effect I wanted that was at least more fun than the whole area exploding immdeiately on impact. However, I explored a more physics-based approach that looked a lot more satisfying. I simply turned the elements’ rigid body component from kinematic to non-kinematic to effectively enabled their physics. This gave a fun tumbling and physics-y effect for the individual blocks as they interacted with the projectile.

This is a decent spot for most of the elements of this small game project, and I think the next step is just building out a better level to test the individual mechanics in. I would also like to add a bit more to the projectile/environment interaction just to make it a bit more impactful. I would also like to remove the strange interaction of hitting the blocks from above, as without any additional force, they don’t really move since they really start by moving downward with gravity being the only force acting on them.

Sonic Boost – Projectile Tests and Environment Voxel Interactions from Steve Lilley on Vimeo.


Video: Sonic Boom Projectile and Obstacle Destruction Showcase (1st and 2nd Iteration)

via Blogger http://stevelilleyschool.blogspot.com/2021/06/game-project-flying-game-sonic-boost.html

Game Project: Flying Game – Part 2 – 3D UI Guide with Rotational Matrices

May 4, 2021

Flying Game

UI & Matrix Rotations


Overview

I wanted to make a 3D UI element which could direct the player in open flying space towards a point of interest or goal. This needed to point towards the object positionally, as well as account for the rotation or direction the player is facing. This makes sure that no matter where they are and what direction they are facing, it can guide them to turn the proper direction and make informed decisions to move directly towards that goal.

After deciding that changing my frame of reference could be a solution for this problem, I found Unity’s InverseTransformDirection method which can change a Vector from one space to another. To make sure this was providing a result similar to what I expected mathematically, I also wrote out the math for performing a matrix rotation on the vector and was happy to see it gave the same results.

3D UI Element – Real Time Guide Towards Goal

Add a 3D Element to the Unity Canvas

You change the render mode of the Canvas to Screen Space – Camera, which requires adding a Camera reference. To satisfy this, create another Camera separate from the main with the above settings. Drag this Camera in as the reference for your Canvas. Now 3D objects can be added to the Canvas.

Make sure the 3D elements added are on the UI layer. Sometimes the scaling can be strange, so you may need to scale the objects up substantially to see them on the Canvas. Also your main Camera may separately render the object as well, so to avoid this remove the UI layer from the Culling Mask for your main Camera.

    Canvas Settings:

  • Render Mode = Screen Space – Camera
  • Render Camera = Created UI Camera
    UI Camera Settings:

  • Clear Flags = Depth only
  • Culling Mask = UI
  • Projection = Orthographic

Unity’s InverseTransformDirection to Set Guide Upward Ray

Using Unity’s “InverseTransformDirection()” method from the player’s transform with the vector pointing from the player’s position to the intended goal allowed me to change the frame of reference of the goal vector from world space to that of the player. This properly rotates the vector to associate itself with the player’s current rotation as well as their position relative to the goal.

Creating my Own Rotational Transformation on the Goal Vector to Compare to Unity’s InverseTransformDirection

To double check what this was doing, I found the math to change the frame of reference of a vector from one frame to another at the link attached. Since the player currently only rotates on a single axis (the y-axis in this case), I could directly copy the example seen in the video which investigates representing a vector in a new frame with a rotation about a single axis (to keep the terms simpler for now). Following this math I got the exact same results as Unity’s InverseTransformDirection method, indicating they perform the same operations.

Creates Vector from Player to Goal

private Vector3 PointTowardsGoal()
{
	return goal.position - player.transform.position;
}

Transforms Goal Vector from World Space to Player’s Space with Unity InverseTransformDirection

private Vector3 PointTowardsGoalRelativeToForward()
{
	// Translate direction to player's local space
	relativeDirectionFromForwardToGoal = player.transform.InverseTransformDirection(PointTowardsGoal());

	return relativeDirectionFromForwardToGoal;
}

Transforms Goal Vector from World Space to Player’s Space with Rotation Matrix Math

private Vector3 GoalVectorInFrameOfPlayer()
{
	// pr
	Vector3 originalVector = PointTowardsGoal();

	// Obtain rotation value (in radians); Rotation angle about the y-axis
	float theta = player.transform.localRotation.eulerAngles.y * Mathf.PI / 180;

	// p1
	Vector3 vectorInNewFrame = new Vector3(
		originalVector.x * Mathf.Cos(theta) - originalVector.z * Mathf.Sin(theta),
		originalVector.y,
		originalVector.x * Mathf.Sin(theta) + originalVector.z * Mathf.Cos(theta)
		);
		
	return vectorInNewFrame;
}



Flying Game Project: 3D UI Guide Towards Goal Prototype from Steve Lilley on Vimeo.

Video 1: Prototype of 3D UI Guide Using Unity InverseTransformDirection




Flying Game Project: Comparing Unity's InverseTransformDirection to my Own Rotational Matrices from Steve Lilley on Vimeo.

Video 2: Update Using Rotational Matrix Math on Goal Vector

Summary

It is good to know that for standard procedures where I want to change the relative frame of a vector that Unity’s InverseTransformDirection() method appears to do that. As showcased here, that can be a very strong tool when you need to translate vector information from your game’s world space to an element in your UI, whether that be through the player’s current frame reference or something else.

Learning how to setup a Canvas to use 3D assets in your UI is also good to know just to increase the flexibility of options you have when creating a UI. Some information can be difficult to convey with a 2D tool, so having that option can open avenues of clarity.

via Blogger http://stevelilleyschool.blogspot.com/2021/05/game-project-flying-game-part-2-3d-ui.html

Game Project: Flying Game – Part 1 – Introductory Movement and Camera Controller

April 30, 2021

Flying Game

Game Project


Overview

I wanted to do some work on a small, simple 3D game in Unity I could make within a week or so. My original focus is on player movement, and from there I decided to hone in on a flying game of some kind. I have been watching Thabeast721 on Twitch and he recently played Super Man 64 which I have also seen at Games Done Quick (GDQ) events and thought building off of and improving their flying controller could be a fun project.

Player Controllers

Controller #1 – Rotate Forward Axis

My initial thoughts on a basic flying player controller was to have left/right rotate the player on the y-axis, up/down rotate the player on the x-axis, and a separate button to propel the player in their current forward direction.

As a controller standard, I also tend to have the player’s input be received in the Update method to receive as often as possible, but then output these inputs as movement in FixedUpdate to keep it consistent on machines with different frame rates.

	private void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        verticalInput = Input.GetAxisRaw("Vertical");

        if (Input.GetButton("Jump"))
        {
            isMoving = true;
        }
        else
        {
            isMoving = false;
        }
    }

    private void FixedUpdate()
    {
        // Inputs in reverse position for direction vector because that influences which axis that input rotates AROUND
        Vector3 direction = Vector3.Normalize(new Vector3(verticalInput * inversion, horizontalInput, 0.0f));
        Flying(direction);
    }

    private void Flying(Vector3 dir)
    {
        RotatePlayer(dir);
        MovePlayer(dir);
    }

    private void RotatePlayer(Vector3 dir)
    {
		transform.Rotate(dir * rotationSpeed * Time.deltaTime);
    }

    private void MovePlayer(Vector3 dir)
    {
		if (isMoving)
		{
			transform.position += transform.forward * movementSpeed * Time.deltaTime;
		}
    }

Controller #2 – Rotate on Y-Axis but Translate Directly Vertically

With my second approach I wanted to try and emulate the flying controller from Super Man 64 just to see how it felt. It seems like a more acarde-y style of flying with easier controls, so I thought it would be a good option to investigate. For this horizontal rotation (rotation on the y-axis) remained the same, as this is pretty standard with grounded player controllers as well.

The up and down rotation (rotation on the x-axis) however, was completely removed. The up/down inputs from the player simply influence the movement vector of the player, adding some amount of up or down movement to the player. This makes it much easier to keep the player’s forward vector relatively parallel to the ground and is much less disorienting than free-form rotational movement in the air.

	private void Start()
    {
        if (isInvertedControls)
        {
            inversion = -1.0f;
        }
    }

    private void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        verticalInput = Input.GetAxisRaw("Vertical");

        if (Input.GetButton("Jump"))
        {
            isMoving = true;
        }
        else
        {
            isMoving = false;
        }
    }

    private void FixedUpdate()
    {
        // Inputs in reverse position for direction vector because that influences which axis that input rotates AROUND
        Vector3 direction = Vector3.Normalize(new Vector3(verticalInput * inversion, horizontalInput, 0.0f));
        Flying(direction);
    }

    private void Flying(Vector3 dir)
    {
        RotatePlayer(dir);
        MovePlayer(dir);
    }

    private void RotatePlayer(Vector3 dir)
    {
		transform.Rotate(dir.y * Vector3.up * rotationSpeed * Time.deltaTime);     
    }

    private void MovePlayer(Vector3 dir)
    {      
		if (isMoving)
		{
			Vector3 movementDirection = Vector3.Normalize(transform.forward + dir.x * Vector3.up);
			transform.position += movementDirection * movementSpeed * Time.deltaTime;
		}     
    }

Camera Controller

Follow Position

To follow the player’s position, I am using a really simple case where it just follows them at some fixed offset. The offset is originally determined by the initial position of the camera relative to the player, and then for the rest of its run its position is just that of the player summed with the offset.

Where transform.position is the position of the camera object:



offset = transform.position – player.transform.position;



transform.position = player.transform.position + offset;

Rotate to Follow

My first test just to initialize the camera follow was to child it to the player to see how it looked that way. This worked ok for following position, but having multiple rotation influences made this impossible to use quickly at first. As I changed the player controller to a more general, arcade-style, it worked better but was still poor for rotation.

To fix this I put the camera as a child onto a separate empty gameobject. This gameobject could then follow the player and rotate to rotate the camera around the player while keeping it at a fixed offset distance. This also made determining the rotation angle/looking vector from the camera to the player much simpler. Since the camera is rotate downward some, its forward vector is not in-line with the world z-axis anymore. This camera container however could keep its axes algined with the world’s axes. This meant I could just make sure to align this container’s forward vector with the player’s forward facing vector on the xz-plane. To do so it just required the following:

private void RotateView()
{
	Vector3 lookDirection = new Vector3(player.transform.forward.x, 0.0f, player.transform.forward.z);

	transform.rotation = Quaternion.LookRotation(lookDirection, Vector3.up);
}

Unity’s Quaternion.LookRotation method allows me to set the rotation of the object based on the direction of a forward facing vector (lookDirection in this case), with a perpendicular upward vector to make sure I keep the rotation solely around the y-axis.

The following is a quick look at how the final player controller and camera controller interact from this initial prototype approach:

Flying Game Project: Initial Player Controller and Camera Controller Prototypes from Steve Lilley on Vimeo.

Summary

via Blogger http://stevelilleyschool.blogspot.com/2021/04/game-project-flying-game-part-1.html

Personal Game Jam 1 – Getting Started

April 24, 2020

Personal Game Jam

Getting Started

Finalizing Concept Selection

I had reduced the number of concepts from 6 to 3 after creating the initial concept lists by removing all the options from pair B. I really liked most of these concepts, but they were a bit more involved than I was looking for for such a short term project. The main issue with the first two for me was that they involved drawing objects into existence with the mouse, which is a type of input I am completely unfamiliar with. This would have made them a perfect candidate for an experimental game project with 2 weeks of effort, but since I wanted to make significant progress in just two days, this would have set me behind too much. The last concept was more puzzle related, which is difficult to make effectively in this amount of time since they are so level design focused.

To help me decide between the 3 remaining concepts from my pair, pair A, I made really simple concept sketches to get an idea of how they would look. Here are those sketches:

Concept 1: Water and Space Pressure for Expanding and Compressing

Concept 2: Flying Tree Spirit Fueled by Water

Concept 3: Gather Minerals as Polyp to Feed Coral Monster (Phase 1)

Concept 3: Gather Minerals as Polyp to Feed Coral Monster (Phase 2)

Concept 1: Water and Space Pressure for Expanding and Compressing

This concept focused on the difference between the high pressure environment of water and no pressure environment of space. The player would expand over time in space areas, and compress over time in water. Each size has its own pros and cons and the player navigates through an area.

I eventually discarded this concept since it ended up being too puzzle related most of the time, which as I stated before, are a bit too much work to create in a small time period.

Concept 2: Flying Tree Spirit Fueled by Water

The player is a tree entity that uses water as fuel to propel itself through space to find minerals and resources to mine. Water and minerals can be used to grow and upgrade the player.

This rather simple concept was a nice mix of simplicity and room for expansion and growth, so this seemed like a promising candidate to move forward with.

Concept 3: Gather Minerals as Polyp to Feed Coral Monster

This game is played in two main phases: a small space polyp phase and a large coral monster phase. The player starts in the polyp phase, and can move between a space environment and an aquatic environment. They search for space coral hearts in the space environment to bring to the water environment so they can plant them and grow them.

The player then feeds these coral hearts to influence and accelerate their growth. They do this in two major ways: finding minerals to bring back to the heart and defeating enemies above the hearts so that they fall onto them. Once the coral heart receives enough resources, it grows into a coral monster which the player takes control of moving into the next phase.

The coral monster created by the player has its parameters altered by the various types of minerals and enemies fed to it during growth. For example, a certain mineral may increase the speed of the coral monster, while certain enemies may have increased the coral monster’s melee attacks. These effects are amplified by having more of a single type of resource being fed to the monster.

I put a lot of thought into this one, but ultimately was unable to come up with a satisfying second phase that made sense with the flow of gameplay. I think this idea has a lot of potential, but needs more time to commit to it to reach a good point.

Concept Selected: Concept 2: Flying Tree Spirit Fueled by Water

Ultimately I chose concept 2 to move forward with. It still needed work to get to an interesting point, but I think it fit the best balance of simplistic foundation with a lot of room for growth depending on how much time and effort I wanted to put into it.

Summary

Again, I was just underestimating the time necessary to put into initial concept selection and creation so that used a lot of my starting time with this project. I need to get better at determining when to let an idea go earlier and focus on the others.

Sketching concepts out is generally helpful for me, but being unskilled with Photoshop was slowing my process down a bit. I normally sketch with pencil and paper and that works well for me, but I want to get better at using Photoshop for this purpose since I think it will bode well for me in the future.

Personal Game Jam 1 – Concept Creation

April 23, 2020

Personal Game Jam

Concept Creation Meetup

Game Jame Idea

I wanted to work on a smaller scale project personally to practice some programming techniques and systems I have picked up recently in a more practical sense, as well as focusing less on long term and large scale scaling of projects. This way I could focus more on trying to find solutions that work as opposed to the best solution, so I could continually progress and try out some new skills I have learned.

This led to this idea of creating a personal game jam for myself following similar rules that I used in an experimental games class to create projects. The game jam approach makes sure I don’t spend too many days on it. I am planning on spending about 5 – 6 hours on it for 2 days and seeing where I get with it.

Initial Concept Generation

The approach we used to come up with inspiration for a small scale project in experimental games was as follows in pairs of 2:

  • Start with a single key word: I chose Earth in honor of Earth Day
  • From that word, choose several words (usually 3) that first come to mind (alternating with partner) to create your tier 1 words
  • Repeat this process with all your tier 1 words to create tier 2 (so usually ~9 words)
  • Repeat until you have 3 or 4 tiers of words (can reduce number of words per word later so you don’t have a ton of words)
  • As a pair, agree on one word from each tier that you like the most (you must include the starting key word as your tier 0 word)
  • Use this group of words as inspiration for several game concepts as individuals
  • Bring them together to narrow it down to your favorites and see what collaborative ideas you can make
  • Flesh these ideas out and finally choose your project topic

We did this process in experimental games with a single partner, but I organized a group with three of my friends, Marino, Nick, and Justin, to do this process online. Since I am the only one actually creating a project, we needed to make some modifications for this process to work with effectively a group of 4.

When choosing our words, I decided to expand it to 4 words per word so each person got to contribute a single word for each word as we expanded tiers (until we got to tier 2, where I just had us do 2 words per word and broke it in half for two separate tiers, 3 and 4).

Here is the list of words we generated:

Generated Word List

Word Selection

I find having to agree on the best words from each tier with someone else to be a useful process, but thought that agreeing on a single word with 4 people would be a bit much. To get around this, I split us into 2 pairs that did the process separately with the same group of words. Here are those lists we generated:

Pair A Words – Justin and I

Pair B Words – Marino and Nick

Initial Concept Building

We stayed separated in our two different pairs here to come up with basic game concepts over the course of 30 minutes. We decided to come up with 3 concepts each as a pair and come together to go over them.

Pair A (Justin and I) Concepts:

  1. You are a large crystalline space coral monster that consumes resources to grow and produce more coral monsters.
  2. Tree person that sucks up water in their roots to fuel a water cannon which propels them into space to mine resources. They can grow and upgrade to hold more water.
  3. Focus on the differences between water and space and the interesting physics each presents, as well transitioning between the two to create interesting game mechanics.

Pair B (Marino and Nick) Concepts:

  1. “Platformer where you can build things out of…WHIPPED CREAM (foamy substance) and you can apply PAINT to give the WHIPPED CREAM different properties. Different amounts of WHIPPED CREAM and PAIN(t) per level. He’s actually just drawing with whipped cream in a big ole’ cup of coffee.”
  2. “Multiplayer??? game where players are shown a beautiful PAINTing to recreate using WHIPPED CREAM. One player is the judge, the rest PAINT. Weird mechanics for the WHIPPED CREAM: gets more liquid-y over time, slides down the page the longer it sits. “
  3. Puzzle platformer where you can paint trees in the environment to match one of the four seasons to give various platforming effects to get through areas.

Final Concept Steps

With these 6 concepts together, I personally took them to build off of them and flesh them out (if possible) to decide on the one to move forward with the next day. I thought Pair B’s concepts were already decently formed so I did not need to spend much time with them, so I mostly needed to focus on building up Pair A’s concepts.

Summary

Overall I think it went pretty well. I underestimated the time needed to come up with concepts and flesh them out, so I will look to give that more time moving forward. I forget from my experimental games class we normally took our words home with us to think of concepts for one or two full days before reconvening to go over what we came up with as a pair, so something like that may be better in the future. I do have to say I was pretty pleased what we were able to put together in just 30 minutes though.

As the organizer of this tiny event, I was the only one sharing my screen for the majority of it to help facilitate the process. I would like to look into something where everyone could possibly draw on the same area (or share their screens to draw on) to help illustrate ideas with simple sketches, since I find that very helpful in this phase.

This was all done in preparation for my personal game jam, so I did not particularly include it in the general game jam time window. This doesn’t really matter since the timing is fairly arbitrary, but I did like having it as its own separate event leading up to my work time instead of also including in the game jam work time like a general game jam would function.