Vladimir Novick
Posted on July 5, 2019
GraphQL is an amazing technology that took the world like a storm. More and more companies are switching to using GraphQL instead of REST APIs because so many things, GraphQL solves.
In a nutshell, GraphQL is a query language for your API. It gives you an ability from a client-side to query your single API endpoint and define a shape of data that you want to get. On the server, you define a schema - the shape of data and how this data is resolved. Whether from a database, microservices or literally in any way you want.
What's also cool, GraphQL gives you subscriptions functionality so you can get real-time data over WebSockets and build modern web and mobile apps with ease. If you are interested to learn more about GraphQL, you can check out learn.hasura.io tutorials on how to use GraphQL with lots of various web and mobile clients.
Also, you can check GraphQL Bootcamp I did some time ago on my Youtube channel
If you've been following me on twitter @VladimirNovick you probably know that I am working on Web, Mobile, AR, VR and IoT fields.
In VR and AR fields especially I've been working with Unity3d engine, so I was recently curious whether I can use GraphQL in Unity3d for things like real-time leaderboards.
After a long search for a graphql client for Unity3d, which I can use in C# and which will be supported in Unity engine, I found really basic one, that I used for the following demo.
So what's happening in this demo?
There are 3 scenes, which I have:
First one is just a loading screen and here I just show basic Loading screen with 10 seconds timer. So nothing really happening here.
Next loaded screen is HasuraSpaceDemo
I used FPS All in One first-person controller and Sci-Fi Modular corridor demo scene. For the portal, I used KTK Lighting asset to reduce time working on particle effects, but basically, it's just the Unity Shuriken particle system using a bunch of lighting assets. For UI and for Portal scene I used Sci fi UI pack and Living particles. Music in the scene is from Dark Sci-fi asset
HasuraSpaceDemo
is used to showcase that GraphQL can be used in any type of game. If you walk into the portal I present UI where you can basically enter any GraphQL endpoint URL. When you do so, you are "teleported" into different - Portal
scene.
I have UIManager
script that handles UI:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : Singleton<UIManager>
{
public string graphQLEndpoint;
public GameObject graphQLCanvas;
private void Start()
{
DontDestroyOnLoad(gameObject);
}
// Start is called before the first frame update
public void LoadPortalScene()
{
GameManager.Instance.loadPortalScene();
}
public void setGraphQLEndpoint(Transform inputField)
{
graphQLEndpoint = inputField.GetComponent<InputField>().text;
}
}
As you can see this script has two public methods - first one to load the portal scene and the second one to set graphQLEndpoint
for later use in the next scene.
To use GraphQL in the next scene, what I do is, first of all, use GraphQLQuery
script from graphql-client-unity package and set it on new empty Game Object in the scene calling it GraphQLClient
Then I need to add a Panel that will have interaction. The idea is when I approach a panel with text "GraphQL Schema Introspection", I will enter into Box Collider which will trigger OnTriggerStay
method in IntrospectionPanelInteraction
script.
When our IntrospectionPanelInteraction
script starts, we set our GraphQuery URL, canvas to display a result as well as canvas content:
void Start()
{
if (UIManager.Instance)
{
UIManager.Instance.graphQLCanvas = canvas;
}
GraphQuery.url = UIManager.Instance.graphQLEndpoint;
fp = FindObjectOfType<FirstPersonAIO>();
content = canvas.GetComponent<UICanvas>().Content;
}
So when we are within Collider borders, OnTriggerStay
function is running.
private void OnTriggerStay(Collider other)
{
if (!canvas.activeSelf)
{
canvas.SetActive(true);
runIntrospectionQuery();
}
InteractionController.Instance.disableInteraction(fp);
}
query execution looks like this:
void runIntrospectionQuery()
{
Debug.Log("Query");
GraphQuery.onQueryComplete += DisplayResult;
GraphQuery.POST(introspectionQuery);
}
the query itself is defined as a string public variable and is visible in the editor:
The final IntrospectionPanelInteraction
script looks like this:
using System.Collections;
using System.Collections.Generic;
using graphQLClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UI;
public class IntrospectionPanelInteraction : MonoBehaviour
{
[Tooltip("This is the query call that gives me introspection details)]
[TextArea]
public string introspectionQuery;
public GameObject canvas;
private FirstPersonAIO fp;
private Text content;
void Start()
{
if (UIManager.Instance)
{
UIManager.Instance.graphQLCanvas = canvas;
}
GraphQuery.url = UIManager.Instance.graphQLEndpoint;
fp = FindObjectOfType<FirstPersonAIO>();
content = canvas.GetComponent<UICanvas>().Content;
}
// Start is called before the first frame update
private void OnTriggerStay(Collider other)
{
if (!canvas.activeSelf)
{
canvas.SetActive(true);
runIntrospectionQuery();
}
InteractionController.Instance.disableInteraction(fp);
}
private void OnTriggerExit(Collider other)
{
if (canvas.activeSelf)
{
canvas.SetActive(false);
InteractionController.Instance.enableInteraction(fp);
}
}
void runIntrospectionQuery()
{
Debug.Log("Query");
GraphQuery.onQueryComplete += DisplayResult;
GraphQuery.POST(introspectionQuery);
}
public void DisplayResult()
{
string data = ParseData(GraphQuery.queryReturn, "__schema");
canvas.gameObject.GetComponentInChildren<ScrollRect>().normalizedPosition = new Vector2(0, 1);
Debug.Log(data);
content.text = data;
}
void OnDisable()
{
GraphQuery.onQueryComplete -= DisplayResult;
}
string ParseData(string query, string queryName){
JObject obj = JsonConvert.DeserializeObject<JObject>(query);
return JsonConvert.SerializeObject(obj["data"][queryName], Formatting.Indented);
}
}
Summary
As you can imagine this is a very simple example and it's me just trying out GraphQL in Unity engine. Also, it's a long way to go to get subscriptions, live queries etc. I am experimenting and I would love to see what use case for GraphQL in Unity3d or Unreal engine will be. I can see it really useful for things like leaderboards, high scores, in-app purchases, in-game ads, etc.
Please let me know on Twitter what GraphQL usage you see in Unity3d.
Posted on July 5, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.