August 28, 2019
Tower Defense Tutorial Project
Testing Losing States
I believe all the moving parts for my scene management system are finally starting to come together and work properly for this project. The losing conditions are the last state I really need to check with. I just need to make sure it properly ends the game when the player loses, does not allow them to progress, displays the proper UI elements, and moves between scenes from the losing state correctly.
GENERAL TESTING
Test #1:
The first test was going to Level 1 from the level select menu and immediately losing.
This seemed to work fine. The game stops when the player loses, and the game over UI comes up. The UI text does not seem to be working properly, so I will have to adjust that. It says the player survived 25 rounds, which is just the default value. I need to tie this into the script controlling the round count.
I think tried Retry and Menu from this losing state and both seemed to work properly. Retry started the level again (and actually reset all the values and waves as well) and Menu took me back to the level select menu.
Test #2:
Open level 2 from the level select menu and immediately lose.
This ended up having the player immediately lose and show the gameover screen as soon as the level loaded. I believe this has to do with how I arrived at the level. I was at the level select menu from the Menu button on the game over (losing screen) of the previous level (Level 1). I think going from losing, directly the the level menu, directly into another level, is missing a reset somewhere.
I did try Retry as soon as I lost level 2 and this reset the level just fine. I also tried selecting Menu and going back to the level, and this only worked properly sometimes. I believe it may have had to do with the timing of the wave.
The issue is that lives in PlayerStats gets set to <=0 to meet the losing condition, but does not get set to a proper value on level start in time. The Base scene loads in, then the Level scene. The Base scene has a check on player lives to see if they have <= 0 for a game over, and the Level scene has LevelInformation which is responsible for setting values like lives. So lives is being checked before being set. This was worked around initially by starting lives at 1 instead of 0, and then anytime the player won they had more than 0 lives so checking a value greater than 0 gave no issue.
POSSIBLE SOLUTIONS: Test #2
My idea to fix this timing issue of the gameIsOver check among other values (like the number of lives) was to move the gameIsOver bool to the GameManager. The GameManager is in the Logic scene, which always persists. This is also where PlayerStats resides, which holds the player lives. My thought with this was that I could have both the gameIsOver bool and the lives be set from the same place at the same time, and with them being in the same exact script, checking against them should be more consistent. Basically, since the game has to be started (gameIsOver == false) as well as having your lives <= 0, if any way of ending the game sets gameIsOver == true, we can make sure gameIsOver is not false until we also set lives first.
SOLUTION: This approach worked (for the most part). I reworked the LevelInitializer script in the Level scene to call StartGame in the GameManager, which just sets the gameIsOver bool to false. LevelInformation is also in the level scene, and this is responsible for setting the lives. This ensures the same scene is setting both the lives and the gameIsOver to false (starting the game). Now the LevelManager checks with the GameManager to see if the gameIsOver is true/false, as well as PlayerStats to see how many lives there are. This basically passes all the value setting and value checking to objects in the Logic scene, which makes sense since it is the omnipresent scene for the project.
This did lead to one issue where losing and retrying the level was not turning the CameraController back on.
PROBLEM: CameraController Bug
The CameraController was not coming back on when losing a level and attempting to retry it.
It turns out that going into a new level was fixing it since the CameraController works by default when loading a new scene, but when the game enters an end state (when we turn off the controller) and we keep the same scene (it’s in the Base scene) like when you call Retry, then it does not come back on.
Test #1:
SOLUTION: Since activating the camera controller was another thing that should happen on level start, I wanted to tie it into the LevelInitializer script. This already had a reference to the LevelManager from my previous attempts at creating Start/End game methods, and the LevelManager had a reference to the camera controller since it was initially solely responsible for controlling the game camera. Using this existing setup, I had the LevelInitializer script go through the LevelManager to enable the CameraController script on the camera object. The LevelManager simply acted as a holder for the camera object and the method for enabling it for this purpose (disabling the camera controller was still handled by the LevelManager when it determined the game had ended).
This ended up working well and gave no errors as far as I could tell.
FINAL NOTES:
With fixing up this last issue, all states and scene transitions should basically be accounted for. Continue, Retry, and Menu all work during gameplay (paused); Continue, and Menu work after beating a level; Retry, and Menu work after losing a level. This should finally be the end of the majority of the scene management work.
NEXT STEP:
The game over UI text is still weird, so I need to fix those references. Also along those lines, it’s only a minor issue, but the game winning text starts at the final round number and THEN counts up again from 0 to the final round number. It isn’t game breaking, but it looks silly.