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.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

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:

After Obj-C

Note: Don’t skip the -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.

Hold on -- this game looks exactly the same as before!

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:

Use Append Here

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!

Note: When you rebuild your Unity game, you’re often given the option to Replace or Append your project. Make sure to select Append:

Use Append Here

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 ” message in your console log as follows:

Welcome Back Notification

You’ve signed in — looks like everything is hooked up and authenticating correctly!

Todd Kerpelman

Contributors

Todd Kerpelman

Author

Over 300 content creators. Join our team.