Develop a Mobile Multiplayer Game in Minutes With Unity and Oracle Backend for Parse
Learn how to quickly develop cool multiplayer mobile games using Unity and Parse APIs and leave the backend work to Oracle Backend for Parse.
Join the DZone community and get the full member experience.
Join For FreeHere, in just a few simple steps, we'll develop a mobile multiplayer game using Unity and Oracle's Backend for Parse.
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.
1. Installing the Oracle Backend for Parse Platform
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, and thus, also providing scaling, microservice, observability, etc., capabilities.
2. Installing Unity and Creating a Project
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. 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.
3. Clone or Download Unity Package
Next, clone or download the Unity package containing the game from the GitHub repos. 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 looks like this:
<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>
2. Second, add the Parse libraries themselves. This can be done in one of two ways:
- Download the lib. 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, i.e., place it at Assets/Plugins/Parse/parse.dll. Note that this is the latest: 2.0.0-develop-1 DLL version. I've included the same in the GitHub repos for convenience.
- Clone or download the src code (again, this is the latest/master branch version of the library) and drop it somewhere under the Assets directory of your Unity project. As before, 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; 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, but note that some of the API names have changed, etc.
Looking Closer at the Unity Project
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 (ApplicationID, ServerURI, 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.
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.
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.
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.
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 not have read it yet, and thus, each player is responsible for deleting their opponent's 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.)
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.
Build and Deploy the App
Under File -> Build Settings, you can simply select the platform (e.g., Android or Apple) to build and run. Additional properties can be edited by clicking the Player Settings button.
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, or 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.
Video
A corresponding demonstration and explanation of the dev process for the game can also be viewed in the following video:
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.
Published at DZone with permission of Paul Parkinson. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments