Last week was more content and art focused as we aimed to implement animations into the game to make it feel more dynamic. I also worked more on the score system, implementing the multiplier aspect and changing the font and look.
Player Plane Animation
As part of our group, I took on the task of animating the player plane so that when you moved left and right, the plane would tilt over like you would see in a real life situation. This was a bit more difficult than expected partially due to my lack of art experience as well as finding top down reference images of planes tilting.
To show the tilting, I decided that the side of the plane that is tilting down will be darker whilst the other side will be slightly lighter to show how the plane is positioned relating to a light. Combined with this, the width of the plane body and length of the wings also changes to give a sense of perspective and gives the illusion that the plane is tilting over from one side to another. The cockpit also shifts around so it looks like you are looking at the side of a plane.
The animation is implemented in Unity using Unity’s built in Animator component and Animation system. This uses a state machine which is common amongst most animation systems where the object has different states that it can transition between. In this case, the plane had 3 states: an idle state, left state and right state with each state having a different animation that changed the sprite of the player plane. To transition between the states, I setup Unity to listen to a parameter that if it matched a certain condition (in this case, if it equaled a number), it would then transition to the new state. It was also setup so that each state can transition to each other as the player could quickly go from left to right, skipping the idle state. The parameter was then set in the PlayerPlane script depending upon which way the player is moving.
Overall, I’m not entirely happy with the result as the transition is very sharp between being straight and tilted and it can be not entirely clear that the plane is tilting over. This can be improved by adding more sprites between the idle state and tilting state to show it tilting over. Another way would be to have different sprites depending on how fast the plane is moving from side to side so if the plane is moving slow, you only see a minor tilt. The biggest constraint that has prevented me implementing these solutions is time as each sprite would need to be created manually. There is a possible solution to that though in that a 3D model is created with a light source above it then it is rendered in different tilting states the images compiled together to form a sprite sheet. The model can have materials applied and shaders used to create the same look as in the game however to develop these would have also taken time and ultimately may not work out faster than the other method proposed.
As an extra to last week, I worked on improving the score system has I wasn’t entirely happy with it. There wasn’t too much that changed with the code, it was more to do with presentation of the score as I was using the default Arial font and the multiplier was not shown.
One of the first things I added was showing the current multiplier in the top left next to the score. This was simple to do by just creating a GameObject with a Text component then updating it from the ScoreManager script. As the score is now showed there, the multiplier part of the ScoreInfo display was removed, just showing the name and score now. When the multiplier value changes, it also “pulses” to show that it has increased, drawing the player’s attention there. Currently, there is no way to show what caused the multiplier to increase and it is something we need to discuss as a team on how we want to balance and award score.
At this stage, I’m pretty happy with how the score system has turned out. It feels satisfying to watch the score counter tick up after killing an enemy and seeing effectively a kill list constantly scroll past makes it feel like you are accomplishing a lot. As mentioned earlier, one thing I would like to change is having a way to display what increased the score multiplier so the player knows and can design a strategy in the future to take advantage of it. Something that could be improved upon is how the multiplier code works and instead of having a dedicated function to set the multiplier, I leverage the use of C# Properties to change the multiplier gameobject size on change.
Part of Eliot’s task was to make it so the gun wasn’t unlimited and would overheat if used too much which he accomplished, allowing fire rate, cooldown and overheat time to be adjusted easily so we can rebalance it as required. However from our own play testing as well as feedback from others who have tried it, constantly tapping the button was exhausting and felt very repetitive so we wanted it so you can instead hold down the button.
The code for this wasn’t particularly complex however figuring out how the desired behaviour in Unity required a bit of research as well as trial and error. The first idea was to detect if the screen was being touched and if that touch was within the bounds of the button area for the gun. This was possible to implement however it would have been some trial and error to get it working correctly as well as adding additional processing time each update check. From the research into this instead, I learned more about Unity’s Event Trigger component. By attaching this component to the GameObject, certain events are fired that the Event Trigger can process and call functions, similar to how OnClick works on the Button component. As such, I created two functions in the EventHandlerUI script that are called when the pointer (for a touch screen, this would be when the user touches the screen) is down or up. These functions then set a variable on the state of the button and in the Update loop, it checks if the button is down and as such, fires the gun.
This system has worked well and should continue to work well for the game. It is a fairly simple change that has not introduced more complex code and is easy to understand.