Building a Turn-Based Multiplayer Game with GameSparks and Unity – Part 4/4
Intermediate Multiplayer Tutorial

Building a Turn-Based Multiplayer Game with GameSparks and Unity: Part 4/4

Welcome back to our GameSparks tutorial. In this final part we’ll set up the Game scene and implement the gameplay. You can find part one, two and three on our blog if you haven’t read them yet.

Gameplay

Before we start implementing the gameplay itself, we need a class that will help us process incoming Challenge messages and store any needed Challenge variables. That way we don’t have to duplicate the same code in each class that needs them. Let’s call it ChallengeManager and make it a Singleton. Add four UnityEvents to it, representing all Challenge messages that other classes could be interested in.

Create a new script called PieceType. It will be an enum representing piece type values on the board (0, 1, 2).

Go back to the ChallengeManager script. Now we can add some public properties and give them values in the message handlers, to make sure they are always up to date.

Add one more method – Move – to make sure that other gameplay classes won’t be referencing GameSparks and won’t need to know how to communicate with the backend directly.

Create a new script called Field. Leave it empty for now. Create a second new script and call it Board. Board’s only responsibility is to spawn fields from a prefab and initialize them with their coordinates. Add BoardSize constant, fieldPrefab and fieldSize fields to the Board.

Now add SpawnFields and SpawnField methods along with their helper, CalculateFieldPosition.

Don’t worry about the compilation errors yet, as we still have to implement Field.Initialize method.

Create a new, empty game object. Call it Board. Add Board component to it and create a prefab.

Create another empty game object. Call it Field. Add Field component to it and create a prefab. Make sure to remove Field prefab instance from the scene. Assign a reference to the Field prefab in the Board prefab.

Go to the Field script now. Its responsibility will be to handle the mouse input when a player interacts with a field and to manage its state based on this input. We’ll use Animator to store Field’s state.

Add a child game object to the Field prefab and add a SpriteRenderer component to it. Add Animator and BoxCollider2D components to the Field prefab root game object. Create a new AnimatorController asset, assign a reference to it in Field’s Animator. Start editing your new AnimatorController in the Animator window. Add three bool parameters, as shown in the image below:

IsHovered, IsHeart, IsSkull.
Fig. 1: Field AnimatorController parameters.

Create states and transitions according to the images below:

State machine diagram.
Fig. 2: Field Animator state machine diagram.
Transition.
Fig. 3: Idle to Hovered transition configuration.
Transition.
Fig. 4: Hovered to Idle transition configuration.
Transition.
Fig. 5: AnyState to Heart transition configuration.
Transition.
Fig. 6: AnyState to Skull transition configuration.

Create four, one frame snapshot animations for the Field prefab. We’ll use transitions to do the tweening hard work for us. Make sure your prefab is set up as on the image below.

Field prefab.
Fig. 7: Field prefab hierarchy.
Idle animation.
Fig. 8: Idle Animation.
Hovered animation.
Fig. 9: Hovered animation.
Heart animation.
Fig. 10: Heart Animation.
Skull animation.
Fig. 11: Skull Animation.

Paste in the following code to the Field script:

One last thing left to make our gameplay complete is a win screen. Create a new script called WinLossPanel. Create a new game object on the Canvas and add a WinLossPanel component to it. Add two Texts (win and loss message) and a Button (back) to it. Make sure to save it as a prefab.

Paste in the following code and assign references to the UI elements in the prefab:

Most of it is pretty straightforward. You just have to remember that there are two separate Challenge events, sent to the winner and the loser.

Other Effects

We won’t cover any additional visual effects here like particles or animated usernames. To see how they were done, download the complete Unity project.

Summary

In a fairly short time we have created a fully functional, server authoritative, multiplayer game. Of course many things could be added, for example:

  • More complicated, tournament rules of Gomoku.
  • Handling disconnected users or allowing users to play multiple games at a time asynchronously.

Try to think of one simple feature you would like to add to the game and implement it as your assignment. This is one of the best ways to learn once you understand the basics of the subject. Don’t forget to share your ideas with us in the comments or on our Facebook page.

4 thoughts on “Building a Turn-Based Multiplayer Game with GameSparks and Unity: Part 4/4”

  1. How can both the MainMenuPanel and the ChallengeManager have a ChallengeStartedMessage listener? Doesn’t the main menu scene call LoadNextScene when it hears ChallengeStarted, and then the ChallengeManager is loaded in the next scene (Game)? So by then the message will already have been missed?

    1. Hi! I should have probably mentioned it somewhere, but ChallengeManager should already exist when ChallengeStarted message is received so you could place it on some object either in Login or MainMenu scene.

  2. Also, can one GameSparks Message have two Listener functions? It seems like whatever gets set second doesn’t run for me (I tried putting the ChallengeManager in the login scene and now its function is the only one that runs).

    Thanks

    1. You can add as many listeners (delegates) as you want. Just make sure you are using the ‘+=’ operator.

Comments are closed.