This is my current portfolio piece that I’m developing. I’m developing the game using C# and Unity 3D version 2019.2.3f1.
The game is about a crystal elemental that has just awoken. It has never felt sunlight, thus the goal of the game is to solve various puzzles to reach the beams of light. The crystal elemental can create portals and teleporting to them. He has a finite amount of teleporters based on the level.
Teleporting in the game is simple. The player will aim at a teleporter and use the action key. I designed the player to utilize a teleporter controller, the player will interpret inputs and direct the teleporter controller. If the player uses the action button, it will cast a raycast forward from the center of the screen. If the teleporter controller finds one, it will set a reference stored within. This is so the player can only teleport to one teleporter at a time. Teleporters work using a state machine, once the player initiates the teleport, the teleporter will warm itself up. Move to the transportation state. From there it will teleport the player and apply any other effects needed. Then move itself to a finished state. The teleport controller will set its current teleporter to none once its determined the state of the teleporter has ended.
To ease my ability to add new portals, I decided to utilize a dictionary asset. The unity asset store dictionary is serialized, allowing me to access it in the editor to make quick changes. The teleporter controller will handle this process in the game. Using a dictionary, I can map prefabs to an enum type called TeleporterType. That way, when the player wants to change to various different portal types, I can simply lookup the prefab to instantiate based on the current TeleporterType set in the teleportercontroller. Currently I only utilize one dictionary, however I have plans to add a dictionary to map the players teleporter inventory.
Database Integration for level management
Update: November 13th 2019
The game now utilizes a SQLite database that is held in the project. Now there is no need to connect from a server. The database reader utilizes query scriptable objects that can be used to either fetch all from a certain table or unique values. In this case, I’m searching through the database to find the scene level names. I find the name by searching for its level id based on our current level. The current prototype only allows for levels 1 and 2.
I wanted to grow crystals from the walls of the caves to make it seem like they’re actually changing and destroying the rock around it as they grow out. This is also to create an established area to help the player know when a crystal is environmental or if its their portal.
I was inspired by a shader video about displacing a mesh to illustrate snow tracks.
Heres the video in question: https://www.youtube.com/watch?v=-yaqhzX-7qo
I noticed that he also changes the color of the and texture of the snow when its a track. Which is exactly what I needed. Currently I have a two shaders and a script to achieve the effect. One shader serves as the base material shader, it holds a two textures to blend and a splat map texture.
The second shader receives coordinates and paints them red on a render texture. Once i send the coordinates to the render texture paint shader, I send the render texture to the base material shader.
It will then lerp the two textures together based on the red value in the splat map.
I added two normal maps to the surface shader to allow for the textures to have normals. It uses the same math to calculate the where to blend the textures, it just applies it to the normal map. Here is the result!
I needed to be able to paint on different materials based on what teleporter you wanted. So i decided to utilize the functionality of a color mask shader to allow for 3 textures to blend together based on the inputed rgb values. Here is the current result.
Modular design using scriptable objects
I watched a Unity talk about the power of scriptable objects for events and variables. I decided to utilize it in my project.
I currently have 2 variables that have a scriptable object implementation; float and int. They inherit from a type generic ScriptableVariable class. They hold a value based on their overridden type.
The second layer of encapsulation for these variables comes in the form of variable references. A float reference for example will hold a constant and a float variable SO(scriptable object). This class has a constructor that allows the value to be set. It also has helper functions called GetValue and SetValue that remove the need to check which value is in use. To determine which variable is being used, it is set by a custom property drawer in the inspector.
I decided to use this approach because it allows for variables to be utilized in other systems through dependency injection.