Softwares / Unity 3D
My skills
- Fast prototyping Game Design ideas.
- Creating game levels: Terrains, objects...
- Importing any kind of content.
- Coding advanced components and features.
- Designing and creating tools to help the production.
- Teaching: using the editor, codding...
- Following various student projects.
Task: Boss fight: Teal'c VS Khufu
11.15.2013Softwares: Unity 3D Microsoft Word
Concept
At the begining it was said I had to work on something epic but trying to avoid adding features because of the deadline.
I started to think about a way to design a generic combat. The best way was to use the tap and sliding quick time events and also, because in this part you are fighting a boss I wanted the player to feel it this way.
So I decided to create this kind of patterns a boss can have and added a healthbar on both character to make a comparison and add tense for the player. To sum up the design, the fight uses randomly chosen sequences of QTEs with different ratio. At first, Teal'c will try to hit his opponent. If he succeed, Khufu looses some health, in the other case, the boss just block and try to counterattack, giving the player a last chance to acheive another QTE to save his character from the death.
Anyway, if he is alive, another sequence is chosen. Maybe Khufu will attack Teal'c and the player will have to block or will see the healthbar decreasing. In anoher case, maybe he will have to make several combos. If he fails Teal'c takes one more hit.
A second part
After, I added a second combat part, like an evolution of the boss. When the player reachs the bottom of Khufu's healthbar, the second sequence starts with Teal'c losing his weapon. In this position the boss becomes harder but the sequence is more like a cinematic showing a more epic combat helping the player feeling the tense of it.
Designing the moves
With the help of other colleagues we made some captures of the most important moves to give the most information we can to the animator. After defining more content, we recorded some videos.
In the first combat, the characters had to go quickly from one move to another if the player succeeds or not.
For the second part, it was something more epic, showing a perfect ending gratifying the player a lot.
Summary
In the last chapter of Stargate: Unleashed, Teal'c is fighting Khufu, a strong opponent.
Work: I designed the boss fight
Task: The savegame
04.22.2010Softwares: Unity 3D
As an adventure game, Contre-Jour has a storyline. So, it was necessary to save the player progress in the game. As well, the game is organized in little levels linked together with some entrances/exits. When the hero moves to another level, the progress is saved in a binary file.
The save concerns different data:
- The player data: coins collected, current level, current entrance in the level...
- The data concerning all the levels: the position of the pushable objects, the coins and items taken, the doors opened, the switches positions,...
- The savable parameters concerning the GSE: To play events only once, ...
To do this, I used a binary file with a specific nomenclature. This kind of file is sequentially organized. A playhead reads or writes the data and moves forward.
The savegame nomenclature
In the main flow
- The player data at first
- The byte number of the whole flow concerning the levels
In the levels flow
The flow contains the total of levels and a list with each level data as items: the number of bytes and each level flow corresponding.
In each level flow
Each flow contains the number of the objects saved and the sequential list of the data for each one. An object data is made of an identifier and a specific flow. (For a pushable crate, we keep the position for example). GSE boxes are handled like other objects but we save the parameters instead.
On the code side
Originally, I used two kinds of basic C# functions.
//Create a file or open the existing one and delete the content
BinaryWriter binWriter = new BinaryWriter(File.Open("myfile.txt",FileMode.Create));
//Write data in the file
binWriter.Write("CJSaveGame");//a string
binWriter.Write(10);//an int
binWriter.Write(10.5f);//a float
binWriter.Write(true);//a bool
//etc.
binWriter.Close();//close the file
if(File.Exists("myfile.txt")){//Verify the file existence
//Open the file
BinaryReader binReader = new BinaryReader(File.Open("myfile.txt" , FileMode.Open));
try{
if(binReader.PeekChar() != -1)//If the file isn't empty
{
//ReadString: read bytes and move the readhead
string str = binReader.ReadString();//a string
int integer = binReader.ReadInt32();//an int
float number = binReader.ReadSingle();//a float
bool boolean = binReader.ReadBoolean();//a bool
}
}
finally{
binReader.Close();//close the file
}
}
Summary
Like all next-generation videogames, Contre-Jour saves automatically the player progress with checkpoints (Here,the level change). Then, the player can go back to the current level if he quits.
Work: I coded the save and load processes.
Task: GSE: Graphical Scripting Editor
03.20.2010Softwares: Unity 3D
Contre-Jour is an adventure game, with a universe, a story, characters. In the game, Charles, the hero, often talks to the fireflies queen, passes a suspicious-looking watchman several times,... In order to set up these events and cinematics, we needed a tool. Then, I created an editor for the team allowing to script those elements directly on Unity3D.
The idea formed at the begining of the production when our ambitions on the screenplay were growing. Inspired by the tool on UDK, the Unreal Kismet, the GSE is a group of several boxes linked to each other by arrows.
Each script starts with an event box (example: a character goes into an area that trigger an event). More boxes are connected to it and make actions (play an animation, emit a sound,...).
A more precise example
Setting up
Set up the GSE wasn't an easy decision. I had to check that the coding time was quick and be sure that the tool was useful and user friendly for the whole team. Then, during a week, I did a prototype with a few boxes. The results were encouraging. In few days, I could do little sequences of simple actions and in use, create box linked was able only in a few drag'n'drops.
The next step was to communicate on the GSE use with the whole team. Some of the group members already knew the Kismet. It was helpful to explain the editor logic. During the project progress, I added more kinds of boxes according to our needs. At the end, we totalized 65 boxes.
Result
Coding this editor saved me a lot of time in scripting events and cinematics. From then on, the team was doing the job. Furthermore, I was able to focus on other features of code.
Summary
I created a tool to easily add events and cinematics in the game. It consists in boxes linked to each other with arrows. Each kind of boxes does its own action.(Play a sound, an animation, show subtitles,...). Based on Unreal Kismet, the tool was helpful beacause I was the only programer and I would work on each event without that. I was able to focus on other code features thanks to this editor, and the other team members were able to do precisely what they were expecting from the game.
Work: Design and code on the GSE tool; teaching to the team.
Task: The Level Streaming
02.05.2010Softwares: Unity 3D
In Contre-Jour, the levels are short and the player ends them quickly. In order to gain time in loading the scenes, I created a level streaming manager.
At the game start, the manager loads the current level where the player characeter is and lanches the game. Next, the level is playable directly but during the game, the manager continues and load the levels directly linked to the one we are playing. For example, when the hero is in the first map ( the red point), the second level is preloaded.
If the level 2 is loaded when the player finishes the first then we go to that level without any loading screen. Arrived in this new place the third one is loading and so on. The first map stays loaded because it's directly linked. We can go back without waiting.
On the code side
The level streaming manager uses a list of all the levels. Each level item is made of a scene to load and a boolean list.
- isLoading: Is the level currently loading
- isDataLoaded: Is the level loaded
[System.Serializable]
public class levelsList{
public string name;//level identifier
public string description;
[System.NonSerialized]
public bool isLoading = false;//Is the level loading
[System.NonSerialized]
public bool isDataLoaded = false;//Is the level loaded
}
public class GameManager : MonoBehaviour {
public LevelsListElement[] levelsList;//List of levels
//...
}
Unity3D contains a simple function to load a scene in asynchronous mode.
private IEnumerator streamLevelCoroutine(int level){
if(!levelsList[level].isLoading && !levelsList[level].isDataLoaded){//We load the level only if needed
//LoadLevelAdditiveAsync: Stream the loading of a scene.
yield return Application.LoadLevelAdditiveAsync(levelsList[level].name);
levelsList[level].isDataLoaded = true;//The level is loaded and available
levelsList[level].isLoading = false;//Loading ends
}
}
Summary
To make a quality game, we decided to minor the time of the loading screen between the levels.
Work: I coded a level streaming manager.
Task: Light/Shadows Rendering
10.05.2009Softwares: Unity 3D
Contre-Jour deals with lights and shadows. The environnement rendering had to be easy to read in order to know in a peek if Charles enchanted shadow is safe or not. I proposed a rendering and tested it with the lead graphic designer during the preproduction.
The solution was to have a distinct limit between the safe shadows areas and the dangerous lights. Each part had to be clearly identifiable and display this rendering had to be technically possible with Unity3D 2.6.
- In light: the rendering is realistic, with colored textures.
- In shadow: The shape of the objects are outlined and we can see some patterns inside. We can determine volumes easily thanks to those.
With the lead graphic designer, we created the first objects using the rendering (the pavillon from the video below). We set up the production pipeline for the graphic assets from these.
How does it work?
The solution is simple, each object is covered with a material that includes two textures.
- The base texture: It is the first layer of the material. This texture reacts normaly to light.
- The lightmap texture: This is a texture that simulate a light. In the deepest dark, colored pixels reveals the base texture under.