I developed a game demo at my school for my diploma. It took a bit more than a year and I was the only programer on this project. I had a bit of help from friends but almost all the programming in the game was made by me.
Below, I'll explain all the main systems I created to make this game.
                                  ​​​​​​​​​​​​​​
Camera

I made a special Camera for this game.
It's a dynamic split camera. When the two characters are far enough the screen will split and rotate depending on the position of the two characters.
I made a page describing how this system works. Click here to go directly there.
It's useful for the players because they can be wherever they want and explore without the need to have their friend near them.
                                  ​​​​​​​​​​​​​​
Powers

Each character has 2 powers.
One of them will controle plants, with the dragon plant and the trampoline plant.
The other will use runes, the wind rune and the shrink rune.
Every power has their own uses.
Destroying obstacles for the dragon,
shrinking Lux to go through smaller holes for the shrink,
bouncing objects or characters for the trampoline,
and lifting objects in the air for the wind.
I created those powers and made it so there is no problems with multiple of them working at the same time.
I made a small optimization to avoid using any Coroutine. It all works via Update or animation and event calls.
                                  ​​​​​​​
Editor scenes

For the development of our game, my team and I decided to work with multiple scenes loaded at the same time. The characters were on a different scene than the powers, wich were on another scene than the plateforms. It made things easier for merging our work together.
With that I needed something to load and unload the scenes as the players progress through the level.
So I did, and I quickly faced a major issue. At first I used the SceneAsset, but I didn't know that it was Editor only, so the system I thought of didn't worked.
With that new knowledge acquired, I decided to make a custom editor.
The Custom Editor made the link between the Editor and the Runtime of Unity.
It works by taking the scenes in the list and transforming them into a new list that contains their names and their directory path. From that I can retrieve the SceneAsset and set it back in the Editor via the path, or load/unload a scene in Runtime via the name.
It made things a lot easier, and prevented a lot of issues like setting a wrong scene, changing names of the scene, or simply putting the wrong scene name in the loader.
And it was way more understandable as you can see below.

SceneLoader without custom editor

SceneLoader with custom editor

                                  ​​​​​​​​​​​​​​
Dialogues

The dialogues of our game are made using TMPro. The dialogue appears with an animation and the text is shown with a Coroutine increasing the max visible character value on the text.
The most difficult part of this system, not that it was actually difficult, was to take in consideration that there were 2 characters in the game.
You have to start the dialogue when a character enters the trigger, but not when the other one enters too. And you need to disable the dialogue when both characters have left the trigger.
                                  ​​​​​​​​​​​​​​
Light and Sound
The lighting of the game is pretty basic. For both characters there is a main light and a secondary rim light, applied using culling masks.
To change the lights when the characters enter a different zone, I have multiple triggers in the level that tells the linked lights to change the intensity and the color to the one specified in the trigger. The color is modified using Mathf.MoveTowards on each R, G, B, and A attributes.
Unfortunatly, the sound wasn't as easy as the light...
We had really big issues when we tried to use Wwise, and because I don't know how to make it work, we had to delete it and use the Unity audio system.
I first started by creating a ScriptableObject to regroup every sound, music, and audio mixer of the game. The script uses different methods to get certain sounds or mixers using Enums.
Then I made a Static Manager which had all the methods needed to call any sound to play or change the music.
When a sound needs to be played it spawns an object with another sound script and initializes it with the correct mixer, AudioClip, and parameters.
       - The position of the object emitting the sound is not the same as the object in the scene. It is actually at the same position as the manager. It is required because we made a coop game and Unity can only have a unique AudioListener (basically the ears).
The sound script on that spawned object is responsible of the initialization of the AudioSource and the sound volume.
When the sound is spawned, it retrieves both players location as well as the location of the object it comes from.
With those locations, it gets the closest distance from the object and players and depending on that value the volume is changed. The further you are, the lower the sound is.
                                  ​​​​​​​​​​​​​​
Itch.Io page soon (WIP)
Back to Top