Unity Certified Programmer:Exam Guide
上QQ阅读APP看书,第一时间看更新

The Killer Wave game framework

We now roughly know what type of game we're going to make. Don't worry too much about the exact details as it will not affect the development phase. Our main focus will be the framework of the game; we'll focus on cosmetics in a later chapter.

It's very easy to jump into game development and make it up as you go along—sometimes, that's half of the fun. But when it comes to the fundamentals of creating any application, we need to know where to throw our creativity and logic by sticking to a particular development process. Ideally, you need a framework.

Before I carry on presuming you know what a framework is, let's just consider it as an overall blueprint—a plan of how all our code is going to talk to each other. Frameworks are similar to design patterns—the plan of the code is set out and ideally shouldn't be expanded on because we're sticking to a plan.

Yes, we know some design patterns, but if the overall flow and direction of our code are lacking scope, we are likely going to run into issues with working ourselves into a dead end. Sometimes, developers think that because they've learned a single framework they can use it to build any application and they use it with every project.

This, of course, is not how we should do it. The more we know about our patterns, the easier the flow of the code will be when it comes to extending our overall master plan or the game's framework.

There are hundreds of ways of making this demo with multiple patterns and frameworks. The one we will follow here is my version, but if you have a better one or one you feel more comfortable with, go for it. As long as you understand the process described in the upcoming chapters and you make use of Unity's APIs on the way, I would encourage you to do this; otherwise, just follow along with our examples.

So, with that said, let's move on to our framework for the game.

Framework

To start off, we will break down what we are going to need for the game. The first things I tend to think of is the player, what the player does, and what's going to interact with our player. We also know that there will be a list of enemies. Finally, the game will likely have multiple scenes, so we need to think about how each individual asset will be set up within each disposable scene. As always, things need breaking down into classes and we need to plan the importance of how classes are connected to each other. The following is how I've broken down the game design brief into separate classes.

These are the class responsibilities:

  • SceneManagerwill globally tell all the classes what scene the user is on (for example, the title screen, level 1, the menu screen, and so on).
  • GameManagercommunicates with all the game objects and communicates with other managers; it is in charge of the game's loop process.
  • ScoreManagerreads and writes the score data when offline and updates the score UI.
  • PlayerShipBuildreceives and sets customization settings to PlayerSpawner.
  • EnemySpawneris similar to PlayerSpawner but it can manage all different types of enemies.
  • Enemyrefers to multiple enemy classes—for example, if an enemy that shoots is made, it will go in this location of the framework. If an enemy moves or acts differently, it will also be put into the same allocation.
  • EnemyBullettravels at a set rate and removes the player after a set time or if it makes contact with the scenery.
  • PlayerSpawnerlaunches the player in a certain location of the screen and keeps its hierarchy in order.
  • Playerfires bullets, receives input controls from the user, and is removed if contact is made with the scenery, enemy, or enemies' bullets.
  • PlayerBullettravels at a set rate, removes and damages the enemy, and removes itself after a set time or if it makes contact with the scenery.
  • ShopPiecehandles the content of the player's ship upgrade selections.
  • SOShopSelectionholds the data types that are used in each grid selection in the shop menu.
  • SOActorModel holds the common variables for each class it is connected to. As an example, all moving objects have a speed setting; this includes player bullets, enemy bullets, enemy ships, and so on.
  • IActorTemplateisn't a class but an interface. An interface works a bit like a contract to whatever it is connected to. For example, this interface wants the class connected to it to have functions titled Attack(), Die(), and so on. The class must include these functions, even if they are empty. You should, hopefully, already know what an interface is; we will be using them frequently in this book. For more information about interfaces, check out https://learn.unity.com/tutorial/interfaces.
  • Additional enemy/player behavior: It is possible to have an enemy that might require more functionality than it has already been given. The same applies to the player. As a precaution, I have sketched in additional classes that are responsible for the extra rotation of the ship, extra particle effects, extra guns, and more.

The following diagram shows the visual relationship between each class that we have just listed. These diagrams are typically called Unified Model Language (UML) (https://subscription.packtpub.com/book/application_development/9781789809770/1/ch01lvl1sec12/understanding-behavioral-uml-diagrams). We could have used a more detailed diagram than the following one, but for the purpose of keeping things as simple as possible, we will just refer to the classes with boxes and names.

Some of you may find this shell-looking framework complex, but both sides mirror each other and control the responsibilities of either game object separately. Let's have a look at this in more detail:

Each gray box represents a class that is mentioned in the preceding list; the lines between each box indicate the inheritance of that class. ThePlayerSpawnerclass, for example, will need to be coupled with the GameManager class to notify it of what is happening to the Player class; the Player class will need to send and receive information such as lives, enemy kill count, and other stats to the GameManager class directly. If we want to move our score over to be stored on the device, then we can link this to our ScoreManager class. The main takeaway from this diagram is that if a line is connected to either box, there will be communication between the classes.

UMLs are not a prime focus for the exam, but they should be mentioned at this stage given that we are creating a plan for the game. I personally like creating UMLs, in a way; as long as the flow of the game is understood, we shouldn't worry about finalizing every detail.

So, now we have an idea of how the game works, how weare going to break it up into segments, and how segments are related to each other. The next step is to prepare our version of Unity and start planning how to bring the game over to this piece of software.