Postmortem
Successes
Our game is fully functional. Our player and prison guards use animated 3D models. We have successfully implemented minigames that can unlock different rooms, the most impressive one being the passcode minigame for which the correct combination is randomly generated every time the game starts and hints appear in the world as to what the correct password is. We have created keys that are able to unlock doors of the same color. We have also successfully implemented the AI for the security guard. It can detect the player and, upon contact, will send the player back to the last checkpoint and subtract 100 from their money. We have also implemented a health system in the form of money. The player starts with $1000 and can acquire money in the world by picking up stacks of cash in the locker room and will lose money every time they are detected; when the player completely runs out of money, the game is over. Additionally, we have an extra challenge in the form of a stamina system; the player has the option to speed up as they run from the guards, but this causes their stamina to decrease which will eventually make them too tired to run until their stamina automatically replenishes itself after a few seconds. We also created a bomb, which is very powerful in terms of its functionality as it can destroy nearby colliders once its timer runs out, and we were able to limit which colliders would get destroyed by their tag.
Challenges
One of the main challenges that we encountered was trying to create holes(carve) in the mesh for the door/key system. One of the main functionalities of our game is that the player is able to unlock/open new locations as they explore the game. The key and door system is pivotal to making that happen but when creating the system we had difficulties trying to figure out how to put doors in the NavMesh whilst also being able to create holes in those same spots. With some research we were able to learn about the component Nav Mesh Obstacle. A recurring issue with it though was that we couldn't figure out how to simply destroy an object because that didn't create a hole in the NavMesh. In order to do that we had to adjust the box colliders on the doors to be roughly outside the range of the NavMesh but also we needed to have the player collide with the door and cause it to move somewhere else. Its movement then creates a hole in the NavMesh. If the door wasn’t in the NavMesh you couldn’t collide with it and if it was in there without the Obstacle component then you couldn’t create a hole in the NavMesh since it can’t be rebaked at runtime. The Obstacle component opened up a whole new list of possibilities.
Another challenge was implementing the stamina bar – first, we had to figure out that the code for filling the bar should go into an empty game object and not the player code, otherwise it wouldn’t work. Then there was the challenge of making the stamina bar actually drain with time instead of just draining upon pressing the shift key – this required getting a reference to the player and its NavMeshAgent in the code for tracking the stamina.
Another key challenge was getting the bomb’s countdown to be synchronized with the countdown in the UI (see the explanation about coroutines below for further detail).
Additionally, we didn’t realize until the second week that we had to improve our game’s camera because certain walls were blocking the view of the player. Fortunately, we were able to develop a system that allows the player to control the camera in-game.
We also had to work over the course of the game to develop and improve the guard AI. This was done by each guard storing their initial position as their center of moving. For each move, the movement is stored as a difference for the next move. Then the next move's random range will be decreased with the difference so the bot remains inside a customized square region. If player is detected and is within a certain distance with the guard, the guard will change its movement pattern from walking randomly inside certain range to pursuing the player. When a guard is in pursuit. it shows an exclamation mark on its head, and when the guard collide with the player, player will be sent to a checkpoint and will lose money for it.
Another part of the process that was challenging was having the game generate a random combination for the passcode minigame and having to implement hints in the actual game as to what the randomly-generated passcode is. Generating the code was one thing where we had a list that filled with random numbers from 1-4 every time the game was run but the biggest concern was trying to implement clues. Originally, we created the game in the sense that there would only be one password but from advice and feedback it was determined that a randomly generated one would prove better. The clues are simply the numbers for the passcode scattered around the map but the biggest issue was knowing what numbers to display in every iteration of the game. Our solution was to create a prefab where there was a sprite with each individual digit childed under it. We had to create empty game objects in the world and we used their transforms to know where to instantiate the numbers. The biggest help with this challenge was the Find() function which allowed us to instantiate the exact number in the passcode no matter what number it was because we already accounted for all the possible digits. Initially the problem seemed very daunting trying to give hints to an ever changing password but with the use of empty game objects and the find function we were able to make it work.
What you learned
One key thing we learned was that using coroutines is not a very good solution. Making a call to StartCoroutine() inside Update() or FixedUpdate() will have the unfortunate consequence of generating multiple coroutines. Also, WaitForSeconds() cannot be interrupted and you cannot see the amount of time elapsed during the WaitForSeconds() process. We realized this in the process of writing the code for the bomb. The bomb was able to function correctly with coroutines in its script, but we realized when it was time to implement the bomb’s countdown in the UI that coroutines have certain deficiencies. For instance, the coroutine was useless when it came to updating the amount of time elapsed to display it in the interface. Our initial solution was to update the timer using a different variable for the time remaining and time.DeltaTime inside of Update(), alongside the coroutine. However, we ultimately decided to scrap the use of coroutines entirely.
Also, we’ve learned that it is more complicated to make the doors on Navmesh. This is because the Navmesh cannot change once baked. Additionally, NavMeshObstacle can Carve the NavMesh with a region similar to a box collider so once the object is moved instead of being destroyed the mesh will be carved again. If the gate is destroyed the player will still be unable to navigate to the area behind the object until the gate is moved; in short, destroying the object does not clear the path, only moving it does.
Possible future revisions
If we had more time in the future, we would include other prisoners and their stories as part of the game’s narrative and for the player to interact with those prisoners. This idea has been on our minds since the start of the development process, however we didn’t have enough time and there were a lot of other aspects of the game which required more attention, including the doors/keys system, the minigames, and the UI. We also could include an animation and a special audioclip for the player being arrested right before they go back to the beginning position. We also could have added a more advanced NavMesh package which would allow us to make a longer game. Also, we could add some more minigame puzzles. We would also add models to the door instead of plain colors which match their keys.
Files
Get Prison Escape
Prison Escape
Status | Released |
Authors | mariasandu, Sojiadenusi, kevinnc, Charles Pan |
More posts
- SourcesApr 08, 2022
- Development ProcessApr 08, 2022
Leave a comment
Log in with itch.io to leave a comment.