Making a game with unity is super cool. But what about online features like saving some data to a database like user info, progress, items, enemies...? You may familiar with node and rest api, but to sending a request from unity and handling received data is a bit itchy in unity.
So let's throw a blog series with unity and node. Then we gonna host it on heroku!
In this part we'll make our "Hello World" project.
Here is the project link on github.
If you've never heard about rest api, I recommend to first check out this tutorial to understand what it means.
Then, lemme write some code.
First open a terminal and initiate our node project file.
npm init
Second, installing express.
npm install express
Make our entry point. Let's call it app.js.
touch app.js
Open the freshly created file with your favorite code editor(mine is vscode in this case) and import express.
const express = require('express');
const app = express();
Our app should listen a port, 3000. Second parameter, a callback, write a message to console.
app.listen(3000, () => console.log('started and listening.'));
One last step before run. When you ask to our app, we should respond back to user. In express this process stupidly simplified with below. When we hit localhost:3000
or make a call with postman our app will respond on certain endpoints. For the hello world project let's respond on home directory '/'.
If you're struggle with what an endpoint means or api ,http callback protocol, I recommend again to first check out this tutorial.
app.get('/', (req, res) => {
res.send('Hello Unity Developers!');
})
Let's take a look to our code before we run.
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello Unity Developers');
})
app.listen(3000, () => console.log('started and listening.'));
Open a terminal and run the code.
node app.js
If no error occured, we should see our console.log on terminal.
Now let's test it before switching to unity.
Go to your browser or postman to test our address localhost:3000
.
Seems working!
So we have made a working service that replies when we ask. How do we do in unity?
Luckily unity have some http callback wrappers.
Let's open a fresh empty unity project and create an empty GameObject in our scene, rename it as 'client'.
Now create a c# script in the Project folder, I'll name it ClientAPI.
In that script we should add a new namespace before we write any code.
using UnityEngine.Networking;
Then we will define a method that returns an IEnumerator
that enables async-like functionality in unity. If you're not sure how to use unity coroutines, this resource might be a good start.
public IEnumerator Get(string url)
{
}
To make a web request let's define a new UnityWebRequest
public IEnumerator Get(string url)
{
using(UnityWebRequest www = UnityWebRequest.Get(url))
{
}
}
I'll put a link for why we need a using statement here. Also check-out unity docs for further reading.
This part is where couroutine magic involves. We should use yield return keyword
when sending a request, it will make sure the process complete until it's done.
public IEnumerator Get(string url)
{
using(UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
}
}
Afterwards, check for errors.
public IEnumerator Get(string url)
{
using(UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.Log(www.error);
}
else
{
}
}
}
If no errror, then it's completed succesfuly.
We have revieved some data from http connection but we should parse these as a string to further work. We'll feed the data as www.downloadHandler.data
from our api. Return our parsed data as string.
public IEnumerator Get(string url)
{
using(UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.Log(www.error);
}
else
{
if (www.isDone)
{
// handle the result
var result = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
Debug.Log(result);
}
else
{
//handle the problem
Debug.Log("Error! data couldn't get.");
}
}
}
}
And define a public variable to provide url.
Now let's give it a go, call our method on Start
. To use coroutines, we have to call it as StartCoroutine()
otherwise it won't work.
Take a look to whole script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class ClientApi : MonoBehaviour
{
public string url;
void Start()
{
StartCoroutine(Get(url));
}
public IEnumerator Get(string url)
{
using(UnityWebRequest www = UnityWebRequest.Get(url)){
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.Log(www.error);
}
else
{
if (www.isDone)
{
// handle the result
var result = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
Debug.Log(result);
}
else
{
//handle the problem
Debug.Log("Error! data couldn't get.");
}
}
}
}
}
Jump back to the unity editor and add script to client GameObject.
Next, enter our address to url.
Now hit play.
We should see the message on the console if you succeeded.
Wow! isn't that cool?
Our server and unity client works like a charm. Congrats!
Here is the project link on github.
BONUS
Let's add some trailer images to make some hype about next parts :)
Top comments (11)
can you make a tutorial using nodejs and socket.io in unity, please
Unfortunately, socket.io wrappers for unity on assetstore and github are abandoned or debrecated. Paid packages available but I don't prefer them for a blogpost tutorial.
Let me know if you find an updated non-paid version for unity.
Try Colyseus
I'm already use it, pretty neat
Thanks for the suggestion, looks promising. I'll dig in!
My guy, when is the second part dropping? 😄
This is really cool and I would love to learn more!
Thanks man👍! I'll make it quick asap 😎🤓
nice
thanks!🤗
Thanks man really appreciate it. Good stuff!
Good to hear positive feedback. Thanks for it :)
Thanks for the useful content.