Creating a Cross-Platform Multiplayer Game in Unity — Part 1
Learn how to create a cross-platform multiplayer game in Unity in the first of a fourth part tutorial. By Todd Kerpelman.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Creating a Cross-Platform Multiplayer Game in Unity — Part 1
40 mins
- Getting Started
- Running on a Real Device
- Understanding Circuit Racer
- Introducing Google Play Game Services
- Setting Up Google Play Game Services
- Registering Your Game
- Turn-Based vs. Real-Time: A Quick Primer
- Adding Testers
- Installing the Unity Plugin
- Adding Missing Frameworks
- Adding More Frameworks
- Adding the -ObjC Flag
- Signing in the Player
- Improving the Sign-In Process
- Adding a Sign-Out Button
- Where to Go From Here?
Adding the -ObjC Flag
Finally, head back to XCode and select the Build Settings tab for your target. Find the Other Linker Flags option — it’s in the Linking section. Double click the part that reads: -weak_framework CoreMotion -weak-ISystem, then click the + button at the bottom of the dialog to add the -ObjC
flag. Your project should look like this once you’re done:
-ObjC
step above; it’s a particularly insidious error because your code will compile and build just fine without it. But when you try to make a call, your project will crash with a mysterious unrecognized selector
message.Now you can finally go back and run your game again! Click the Run button, and if all has gone according to plan, you should see your Circuit Racer running on your device.
True, the game looks the same as before — but there’s a whole slew of code and libraries underneath just waiting for you to make use of them! :]
Signing in the Player
Your first task will be to sign in the user when they click the multiplayer button. If you can get that piece working, you know you’ve set up the game services correctly and you can move on to the more interesting parts of developing a multiplayer game.
Create a new class to handle some of your multiplayer code. Double-click the Scripts folder in the Unity Assets panel. Then right-click the assets panel, select Create\C# Script and name the new script MultiplayerController. Double-click to edit the script in your code editor of choice.
Add the two following imports to the beginning of the file:
using GooglePlayGames;
using GooglePlayGames.BasicApi.Multiplayer;
Next, find the following line:
public class MultiplayerController : MonoBehaviour {
…and replace it with the following:
public class MultiplayerController {
Then delete the two boilerplate Start()
and Update()
methods.
If you’re fairly new to Unity, you might not recognize what’s happening here. You’re creating a piece of code that won’t be attached as a component to a Game Object; instead, you’re creating the object purely in code. With this approach you can’t use MonoBehavior
as your base class; you can either use ScriptableObject
as your base class, or, as in this situation, nothing at all.
Next, add the following content your class so that it’s created as a singleton:
private static MultiplayerController _instance = null;
private MultiplayerController() {
// Code to initialize this object would go here
}
public static MultiplayerController Instance {
get {
if (_instance == null) {
_instance = new MultiplayerController();
}
return _instance;
}
}
Not sure what a singleton is? It’s a common coding pattern where you create one (and only one) instance of an object that can be easily referenced by other classes in your project.
In Unity, creating a class as a singleton can be useful when you need to use it across multiple scenes. The UserPreferences
object is a good example, because it’s an object you need to access from the main menu, the game, and many other sub-menu scenes. Similarly, you’ll need to access MultiplayerController
from both the main menu as well as in the game, so it helps to implement this as a singleton as well.
In order to access the object in the future, you won’t look for specific game objects or create new objects. Instead, you’ll call the static MultiplayerController.Instance
method, which either creates the singleton if it doesn’t yet exist, or returns the one that’s already been instantiated.
Note: Want to find out more about singletons? Check out Eli Ganem’s excellent iOS Design Patterns tutorial on this site for more detail.
Some coding aficionados aren’t terribly fond of singletons, and claim that singletons suffer from overuse. That’s a debate for another time — right now, you’ve got a game to make! :]
Note: Want to find out more about singletons? Check out Eli Ganem’s excellent iOS Design Patterns tutorial on this site for more detail.
Some coding aficionados aren’t terribly fond of singletons, and claim that singletons suffer from overuse. That’s a debate for another time — right now, you’ve got a game to make! :]
Next, modify the code inside MultiplayerController()
as follows:
private MultiplayerController() {
PlayGamesPlatform.DebugLogEnabled = true;
PlayGamesPlatform.Activate ();
}
The first line sets your logs to be nice and verbose, and the second line tells the PlayGamesPlatform
to initialize itself.
Next, add the following method to your class:
public void SignInAndStartMPGame() {
if (! PlayGamesPlatform.Instance.localUser.authenticated) {
PlayGamesPlatform.Instance.localUser.Authenticate((bool success) => {
if (success) {
Debug.Log ("We're signed in! Welcome " + PlayGamesPlatform.Instance.localUser.userName);
// We could start our game now
} else {
Debug.Log ("Oh... we're not signed in.");
}
});
} else {
Debug.Log ("You're already signed in.");
// We could also start our game now
}
}
This is your basic sign-in logic. Calling PlayGamesPlatform.Instance
brings up Google Play’s own singleton instance. The first if
statement checks to see if the local player is signed in. If not, then you call the platform’s Authenticate
method, which attempts to sign the user in.
Also notice that the argument you’re passing to Authenticate
is, itself, a function. Since Authenticate
might take a while to execute, you pass in a callback function to execute when Authenticate
has completed; this is similar to blocks in Objective-C.
Now that you have a method to sign the user in, you need a place from which to call it.
Open up MainMenuScript.cs
, found in the MenuStuff folder. Find the following line in OnGUI()
:
Debug.Log("We would normally load a multiplayer game here");
…and replace it with the following:
MultiplayerController.Instance.SignInAndStartMPGame();
This calls SignInAndStartMPGame()
which you created just a moment ago.
Build your project:
Don’t select Replace, unless you feel like re-doing all those setup steps in the Fixing Your Xcode Project section all over again. I know I don’t!
Don’t select Replace, unless you feel like re-doing all those setup steps in the Fixing Your Xcode Project section all over again. I know I don’t!
Once you have built your project, run the app. Click the Multiplayer button once your application launches; you’ll be taken to a screen where you’re asked to sign in. Use one of the accounts you listed as a “Tester” account earlier in the tutorial. Click Accept and you’ll be taken back to Circuit Racer where you should see a “Welcome back!” graphic appear at the top of the screen and a “We’re signed in! Welcome
You’ve signed in — looks like everything is hooked up and authenticating correctly!