Part of our task this week was to research about the Nexus 9 tablet (our primary target device for the game) to learn it’s capabilities. We looked into the hardware of the device, the history and possibly future of the device and entire Nexus 9 as a whole. Each section of the research project was assigned to each member with myself writing about the core hardware of the Nexus 9 including CPU and GPU.
However more work on the game was also completed this week with the accelerometer controls almost fully finished (just needs some fine tuning), the pause menu is semi functional (some menus need to be created), enemies now infinitely spawn in different formations and enemies also fire and can kill you! Lots of features completed but still more to work on until it is complete and fully playable.
This week we wrote a 2000 word report on the Nexus 9 tablet by Google covering the hardware as well as some of the history and future of the Nexus tablet and devices. The report can viewed here. I wrote the section on some of the core components of computer devices which is the CPU, GPU and screen in this case.
The report went rather well as we all sat down as a team and discussed which areas we was to work on, splitting up some sections between multiple people as we felt they needed to be expanded on more compared to other sections. Finding reputable sources was a little difficult for some areas as some sources was new agencies purely dedicated to reporting on Android so there may have been a slight bias in favour of them. For the Tegra information I also used Nvidia’s Whitepaper on it which will have some bias so I just used the pure facts (such as what was supported) from it.
The Nexus 9 is a very powerful tablet in the current market with a low price. The use of a Tegra K1 SoC has given it good processing power as well as great graphics capabilities. The use of a 4:3 aspect ratio for the screen is rather unusual but after using the device myself I don’t notice any major downsides compared to use a more traditional sized screen. The tablet had its issues at the start with issues related to the buttons being too flat as well as light bleed from the screen but these was fixed after a few months and previous owners was able to get their old tablets replaced with the fixed versions. The Nexus line seems to be moving more towards phones and phablets (large phones) with the recent releases of the Nexus 5X and 6P, this may change though as Google often use their Nexus line to showcase new Android features.
Last week, I polished up the accelerometer controls for the player plane to make it smoother for the player to control as well as fix some bugs from the original code such as unlimited speed. There is still more work that can be done on the controls and there are some issues with it currently that needs to be investigated and fixed but it is in a playable state and it is actually pretty fun to control. Tilting the device left and right (changing the x axis) moves the plane left and right and tilting the device backwards and forwards (changing the y axis) allows the plane to move forward and backwards a little.
One of the first things I implemented was the accelOffset which stored the reading of the accelerometer (effectively the devices orientation) when the players plane is created at the start of the game and treats that as the origin. This means that movement is based off how the device is changed from when the game has started allowing the player to choose how to hold the device that is most comfortable for them whilst still having full movement capabilities within the game. The x for the origin however is overridden and set to 0 as from my own playtesting, I found it can be easy to accidentally hold the device at a slight x angle when starting the game and causing the game to feel “tilted” when controlling it if the offset x wasn’t set to 0.
There is a small issue with the offset currently in that some cases it does not always set it correctly and uses the default offset of a zero vector. This could be due to Unity not having initialised the accelerometer controls within the device causing it to read as zero however there are ways I can deal with this issue. One way would be to set the offset in the very first Update call or to set the offset in Update if the offset is a zero vector. This means that the script will always try to set it as long as the offset is default which is the device laying flat and it is highly unlikely a player would be using it in that orientation. Another solution would be to take the average orientation that the device is held whilst the player is in the main menu screen and find the average position and use that as the origin. This would be a more complex solution and there is a chance that the player holds the device is a different orientation in the menu compared to the game for their own ease so it is not a solution I will be using.
The min(X/Y)TiltAngle was implemented so only mostly deliberate movements make the player move in the game and to make it feel smoother. Before this was implemented, even the slightly tilt to the device would make the plane move, making it very hard to stay in one position on the screen. However now you have to tilt the device by a certain amount (taking the offset into account) in order for the plane to start moving in the world, allowing you to more precisely control it. The variables are set to public allowing us to easily edit it as required via the Unity Inspector panel and it can even be adjusted whilst we test it live to save having to rebuild the game every time. The minimum angle can also be changed independently for the x and y axis. In the future when we implement the settings menu, we can allow the tilt angle to be adjusted so the user can tweak it to how they like by adding slider controls to the menu and linking a callback to adjust the value of the angles.
As we wanted to get a functional game by the end of this week, I decided to work on being able to spawn enemies after the current enemies had been killed to allow for effectively endless mode. This was a bit simpler to implement than I expected thanks to Unity’s Prefab system allowing for enemies to spawn in set positions and edited in the editor rather than needing to specify each position in code.
To accomplish this, I went with a wave based system where enemies spawn in waves rather than randomly over time to allow us to design different enemy encounters. Each wave is called a “formation” as the enemy planes would be in set positions, similar to a formation in real world applications and after each wave/formation is destroyed, a new one is randomly selected then spawned in. Each formation is a collection of enemies that are a child of an empty GameObject with the parent GameObject being called what the formation is for our ease. It has to be done this way as Unity can only create a Prefab for a GameObject rather than a collection of them but if that GameObject has children then those are included as part of it.
The formations are currently selected at random from a list of Prefabs. This list can easily be edited in the Inspector interface in Unity allowing for new formations to be created easily then added to the list without needing to edit the code speeding up the development process of the game. This system is very limited at the moment though, it only randomly selects a formation from the list and if there is a limited number of formations, it could cause the same one to be spawned in a row. There are many ways that this can be expanded though and it forms a basis for future expansion.
One such way it will be expanded in the future is having a list that isn’t randomly selected from but it spawns the formations from top to bottom either after a set amount of time or when the previous formation was destroyed. This system will be the basis for our levels as it allows us to set the progression of the level without needing to do massive code changes per level and instead just set what formations should spawn and adjust the formations as required.
However the random selection mode will also stay for an endless level but it can be tweaked and improved so it isn’t as repetitive. Using weighted random to select a formation can allow us to make certain formations appear more often (such as easier ones if they select an easy difficulty) or we can have the selection chance for each formation change depending on previous waves defeated. For example, if the player has defeated a lot of alpha formations, the chance for that to be selected can decrease to allow other formations to be selected then over time, the chance to select the alpha formation rises again. This may be tricky to implement though and time constraints may prevent us from fully exploring this option but it is certainly something to consider for future expansion.
Deploying for Android
Although we already had our game running on Android (as part of our software prototype), we built a new version this week as we had updated the accelerometer controls and added a lot more new features to the game that we wanted to test and play with. We also had a Nexus 9 available too to deploy it to which is our target device so it allowed us to see how it played when used on it.
Building for Android with Unity is very simple. The first step is download and install the Android SDK from the Android Developers website and install one version of the SDK (ideally the minimum target version you are aiming for). An optional but recommended step is to also download the Google Android driver as this can allow you to connect to the Nexus device via the computer and push new builds to it as well as run debugging on the game. After this has been setup, the package name for the application needs to be changed in Unity (and it must be unique as this how different applications are defined). The project can then be built for Android.
There are a few options available when building, most of them are only important for development reasons. Checking “Google Android Project” makes Unity create an Android Studio project which can allow you to edit Android specific parts of it if required. Enabling “Development Build” adds a development watermark to the game as well as enables the last two options which requires the device to be connected to the computer either via USB (using ADB) or on the same network as it. “Autoconnect Profiler” connects Unity’s built in Profiler which allows you to monitor the performance of the game as it’s played on the device. This is useful as you can run the Profiler when the game is on different devices to let you see how the game performs on one compared to another and where you could possibly improve performance. The final option is “Script Debugging” which allows you to monitor variables in scripts and debug the game as it runs.
Changing Texture Compression is required depending upon on the target hardware as some hardware only supports certain compression formats. A flag within the APK will also be set so only the supported hardware can download and install the application with that specific compression. Multiple versions of the game can be released under one Google Play entry however and the device will only download the version that is compatible with it allowing us to target a wider range of hardware whilst not degrading the experience overall.
The latest version can be downloaded here.
The game is now in a playable state where you can fight enemies, increase your score as well as use it on your Android device. As usual, there is still more work to be done but a lot of the core framework is now done so we can start building up on it and adding more features to flesh the game out more.