Develop a Mobile Multiplayer Game in Minutes with Unity and Oracle Backend for Parse

April 25, 2023 | 8 minute read
Paul Parkinson
Architect and Developer Evangelist, Microservices and Converged Database
Text Size 100%:

Here, in just a few simple steps, we'll develop a mobile multiplayer game using Unity and Oracle's Backend for Parse.

A corresponding demonstration and explanation of the dev process for the game can also be viewed in the following video...

 

A brief introduction of Unity and Parse Platform... Unity is a cross-platform game engine developed by Unity Technologies, first announced and released in June 2005 at Apple Worldwide Developers Conference as a Mac OS X game engine. The engine has since been gradually extended to support a variety of desktop, mobile, console, and virtual reality platforms. The Parse Platform is a back-end for mobile developers, open-sourced by Facebook/Meta in 2016, that helps to store data in the cloud, manage identity log-ins, handle push notifications, and run custom code in the cloud. Oracle has created an adapter to take advantage of all the features of the Oracle converged database while using Parse APIs.

 

The first step involves installing the Oracle Backend for Parse Platform. This can be found in Oracle Cloud Marketplace.  After installing, you will have a Parse Server URI that the mobile app will use to access.  The Backend/Platform is very convenient as it automatically provisions and configures the Parse Server and Oracle Database that it uses as well as a Kubernetes cluster that the Parse Server runs on, thus also providing scaling, microservice, observability, etc. capabilities. More blogs and information on this can be found here.

Parse Oracle Backend Marketplace

 

The second step involves installing Unity and creating a project.  Unity Hub can be installed from here and a new project can be created by clicking the "New Project" button. I used the "2D Mobile (Core)" project template, however, any number of project templates may be used and I used version 2021.2.21f1 of Unity, however, any number of versions from at least 2018 to current versions of Unity should work as the Parse library is compatible across many versions as are the Unity resources used for the game. 

Unity New Project Scren

 

Next, clone or download the Unity package containing the game from the github repos: https://github.com/paulparkinson/unity-parse-multiplayer-game

You can simply drag and drop the contents of this repos into the Assets directory of your Unity project and proceed to the "Looking closer at the Unity project..." section.  If interested in how Parse .NET SDK is added to the Unity project you can read the following section.

There are two very simple steps involved in adding Parse .NET SDK to a Unity Project. 

First, add a link.xml file to the Assets directory in the Unity project. This instructs Unity to preserve/include the Parse library in the mobile application build. The link.xml file is included in the repos mentioned and look like this

Copied to Clipboard
Error: Could not Copy
Copied to Clipboard
Error: Could not Copy
<linker>
  <assembly fullname="UnityEngine">
    <type fullname="UnityEngine.iOS.NotificationServices" preserve="all"/>
    <type fullname="UnityEngine.iOS.RemoteNotification" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaClass" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaObject" preserve="all"/>
  </assembly>

  <assembly fullname="Parse.Unity">
    <namespace fullname="Parse" preserve="all"/>
    <namespace fullname="Parse.Internal" preserve="all"/>
  </assembly>
</linker>

 

Second, add the Parse libraries themselves. This can be done in one of two ways...

  1. Download the lib from https://www.nuget.org/packages/parse/absoluteLatest.  Simply download and extract the package to obtain the parse.dll file and drop it somewhere under the Assets directory of your Unity project.  The directory does not matter as far as functionality, however, the convention in Unity is to use a Plugins directory, ie place it at Assets/Plugins/Parse/parse.dll. Note that this is the latest, 2.0.0-develop-1 DLL version and I've included the same in the github repos for convenience.
    OR
  2. Clone or download the src code from here: https://github.com/parse-community/Parse-SDK-dotNET (again this is the latest/master branch version of the library) and drop it somewhere under the Assets directory of your Unity project. Again the directory does not matter as far as functionality, but of course, a logical location is advised.  Using this approach the Parse library will build as part of your Unity project.  This is one of the nice advantages of Parse being open source as you can look and step into the code to understand it or even make contributions to a very welcoming community.

Note that there is some useful information for using Parse from Unity in the documentation found here:  https://docs.parseplatform.org/unity/guide/#getting-started , however, it is based on Parse version 1.7.0 and an older Unity version. As stated above, I am using the latest 2.0.0-develop-1/master version. You can use either, however, note that some of the API names have changed, etc.

 

Looking closer at the Unity project...

Unity Game with Parse Screen

Double-click ParsePaperScissorRockGame in the Scenes directory of the RockPaperScissorsParseGame project.

Above on the left we see the Hierarchy pane with various Unity GameObjects for the game including the buttons, pictures, and sounds. 

On the right, we see the Inspector pane with information and settings about the selected GameObject. In the case of the RPSGameObject we see that a ParseRockPaperScissorsGame C# script is attached.  All of the code for our game is in this one script. Unity allows the variables and actions in a script to be mapped to GameObjects visually.  For example, the buttons that will trigger code, the images that will be displayed when the buttons are pushed, the sounds that will be played when a winner is announced as well as the text, etc.  We can also set the Parse Server connection information as we see here (ApplicationIDServerURI, etc.).  The player name is built into the app itself but could just as easily be dynamically taken from a text field in the game's playboard interface the same way the opponent selection and object to throw are.

In the middle is the Scene panel for visually designing the scene as well as the Game window where the game can be played and tested.

 

Looking closer at the Unity script and Parse code in ParseRockPaperScissorsGame.cs...

ParseRockPaperScissorsGame is a MonoBehaviour which is the base class from which every Unity script derives. It contains a number of key lifecycle methods. We implement two of the most common in our game, Start and Update

The Start method is called only once when the script (or inherently as part of the GameObject it is attached to) is activated. In our Start method, we create the connection to the Parse Server and publicize() that ParseClient so that it is ready for use.  We then populate the drop-down box of opponents with the results of a query to the RockPaperScissorsPlayers class (a class in Parse parlance being essentially a table or document).  One of the great things about the Parse API is its concise simplicity as you can see in the ParseQuery API call here.

Copied to Clipboard
Error: Could not Copy
Copied to Clipboard
Error: Could not Copy
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(client, ROCKPAPERSCISSORSPLAYERS_CLASS);
   var results = await query.FindAsync();
   foreach (ParseObject obj in results)
   {
          opponentsDropDownList.Add(obj.Get<string>(PLAYERNAME));

 

The Parse Dashboard provides an easy-to-use GUI where we can see this data from RockPaperScissorsPlayers as well as the RockPaperScissors class that is used to store the moves made by opponents in the game...

Parse Dashboard

 

As mentioned and shown earlier, the buttons added in Unity for "rock", "paper", and "scissors" trigger corresponding methods in the script when clicked. Here we see the Rock() method.

Copied to Clipboard
Error: Could not Copy
Copied to Clipboard
Error: Could not Copy
public void Rock()
{
 Debug.Log("player throws rock");
 rock.SetActive(true);
 insertPlayerThrow(ROCK);
}

The method sets the rock image to active so that it is visible to the player and calls the insertPlayerThrow method/function which does a SaveAsync/insert call on the RockPaperScissors class used to store opponents' moves. The ParseObject API is used to make such data modifications and there are also convenience API calls such as Increment() which are useful for keeping GameScores, etc. Finally, the variable isWaitOnReply is set to true which is a value checked periodically by the Update() method which we will discuss next.

Copied to Clipboard
Error: Could not Copy
Copied to Clipboard
Error: Could not Copy
ParseObject psrGame = new ParseObject(ROCKPAPERSCISSORS_CLASS);
psrGame[PLAYERNAME] = playerName;
psrGame[OPPONENTNAME] = opponent;
psrGame[PLAYERTHROW] = playerThrow;
await psrGame.SaveAsync();
isWaitOnReply = true;

 

The Update method is called by the Unity engine every frame and is used in our game to check for opponents' moves. Parse has different notification functionality, however, for this game, we are simply polling.  Every frame is too frequent and so we have set the Update method to check every 3 seconds (the FixedUpdate method can also be used for this purpose, however, works slightly differently). The Update method calls the checkOpponent() method which makes the following query to get the opponent's move (using WhereEqualTo calls to build the query), compare and announce a winner via text and the activation of an appropriate sound (rock crushing scissors, paper wrapping rock, or scissors cutting paper). Finally, the opponent's move, having been processed, is issued a DeleteAsync/deleted.  The actual player's move is not deleted at this point as the opponent may have not have read it yet and thus each player is responsible for deleted their opponents move for cleanup. (There is also a, hidden by default, "Delete All My Games" button in the Unity project and the corresponding method it calls to delete all games in case an opponent never checks).

Copied to Clipboard
Error: Could not Copy
Copied to Clipboard
Error: Could not Copy
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(client, ROCKPAPERSCISSORS_CLASS);
query = query.WhereEqualTo(PLAYERNAME, opponent).WhereEqualTo(OPPONENTNAME, playerName);
var results = await query.FindAsync(); 
foreach (ParseObject obj in results)
{
 string opponentsMove = obj.Get<string>(PLAYERTHROW);
 Debug.Log("opponentsMove:" + opponentsMove);
 if (string.Equals(opponentsMove, "")) isWaitingOnReply = true;
 else
 {
  switch (opponentsMove)
  {
   case "rock":
    rockOpponent.SetActive(true);
    if (string.Equals(opponentsMove, playerThrow)) outcomeTextMesh.text = "Tie";
    else if (string.Equals(playerThrow, PAPER))
    {
       outcomeTextMesh.text = "You won!";
       paperWinAudio.SetActive(true);
    }
[...]
await obj.DeleteAsync();

 

There is also special logic in the app for when "computer" is picked as the opponent but nothing particular to Unity or Parse and so the reader is referred to the source code for that.

 

Finally, build and deploy the app.

Under File -> Build Settings you can simply select the platform (eg Android or Apple) build and run. Additional properties can be edited by clicking the Player Settings button

Unity Mobile Build

 

You can also simply hit play in the Unity Engine to test the app and play the game there.

That's it. You can take it from there and build something beyond paper, scissors, rock if you like.  Access to the Oracle converged database makes for many interesting possibilities through all of its data types and features and you will have a powerful data and application backend supporting it with minimal effort so you can just focus on your application.

Thanks for reading and let me know if you have any questions, feedback, or requests for other material and demos. I'm more than happy to hear from you.

Paul Parkinson

Architect and Developer Evangelist, Microservices and Converged Database

Paul is Architect and Developer Evangelist for Microservices and the Converged Database

His focus includes data and transaction processing, service mesh and event mesh, observability, and polyglot data models, languages, and frameworks.

The 18 years prior to this he was the Transaction Processing Dev Lead for the Mid-tier and Microservices (including WebLogic and Helidon)

Creator of the workshop "Building Microservices with Oracle Converged Database" @ http://bit.ly/simplifymicroservices

Holds 20+ patents and has given numerous presentations and publications over the past 20+ years.

Show more

Previous Post

Using JavaScript community modules in Oracle Database 23ai

Martin Bach | 4 min read

Next Post


How to import JavaScript ES Modules in 23c FREE and use them in SQL queries!

Loic Lefevre | 4 min read