{"id":77467,"date":"2018-03-06T18:34:40","date_gmt":"2018-03-06T18:34:40","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=77467"},"modified":"2026-04-15T18:25:28","modified_gmt":"2026-04-15T18:25:28","slug":"calling-restful-apis-unity3d","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/calling-restful-apis-unity3d\/","title":{"rendered":"Unity REST API Calls with UnityWebRequest and Coroutines"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-executive-summary\">Executive Summary<\/h2>\n\n\n\n<p><strong>Unity3D communicates with REST APIs using UnityWebRequest &#8211; the built-in HTTP client that works within Unity&#8217;s coroutine system. Unlike regular C# HttpClient calls (which block threads), UnityWebRequest is designed to integrate with Unity&#8217;s coroutine model: yield return request.SendWebRequest() suspends the coroutine until the response arrives without blocking the main thread. This article covers the two main patterns for calling REST APIs from Unity: simple UnityWebRequest with coroutines for GET and POST requests, and the considerations for choosing between coroutines (Unity-native, runs on main thread) and threads (true parallelism, requires marshal-back to Unity&#8217;s main thread for UI updates).<\/strong><\/p>\n\n\n\n<p>In the process of developing a game, it is often necessary to communicate with a server. Besides the most obvious reason \u2013 having a multiplayer game \u2013 there are certain cases when games need to get or send information to an external entity. In-game payments, global leaderboards or login systems are just a few examples.<\/p>\n\n\n\n<p>While in the multiplayer scenario data is constantly exchanged between the server and the client, the other cases that I mentioned only require a simpler request\/response pair: the client sends or requests some data to the server, and the server performs the required action, while also providing a response to the client. Nowadays, the most common way to solve this problem is to use a RESTful API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-are-restful-apis\">What are RESTful APIs?<\/h2>\n\n\n\n<p>A RESTful API \u2013 or a RESTful web service \u2013 is an interface that can receive HTTP requests (<strong>GET<\/strong>, <strong>POST<\/strong>, <strong>PUT<\/strong>, <strong>DELETE<\/strong>) in order to manipulate data. A RESTful API is easy to scale, due to the loose coupling between the client and the server. Another advantage is the flexibility of the message, which can be sent in the form of XML, HTML, JSON or any other desired format.<\/p>\n\n\n\n<p>This article does not cover the creation of such a web service but trying to do so would be a good exercise for learning how they work. <a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/web-api\/overview\/older-versions\/build-restful-apis-with-aspnet-web-api\">This article<\/a> explains how to create a RESTful API in .NET, but&nbsp; most programming languages are capable of doing this.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-purpose-of-this-article\">The purpose of this article<\/h2>\n\n\n\n<p>What I will do in this article is to present different ways of calling a RESTful API from Unity3D. If you are not familiar with Unity3D, you can read more about what it is and how to install it from this <a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/introduction-game-development-unity-c\/\">introductory article<\/a>. The principles that I present should be applicable to any game engine that allows coding except maybe for the engines that implement their own language.<\/p>\n\n\n\n<p>In order to make the things a little bit different, I chose to use a weather API for this tutorial. The code will check whether or not it is snowing in a particular city and will simulate the same in our game. The code uses the <a href=\"https:\/\/openweathermap.org\/\">OpenWeatherMap API<\/a> for this, since it is free and allows a decent number of requests. Create an account and you will be offered an API key which will be necessary when making the requests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-setting-up-the-project\">Setting up the project<\/h2>\n\n\n\n<p>To begin, create a new Unity3D project. Press the <em>New<\/em> button from the top-right and make sure the <em>3D<\/em> checkbox is selected although you could easily replicate the tutorial in a 2D environment, since this example will not use any 3D-specific features.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"993\" height=\"595\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-4.png\" alt=\"\" class=\"wp-image-77468\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>I created a plane on the scene just to have something simple to look at, but this is not mandatory. Of course, you could also create a more complex scene, depending on your needs.<\/p>\n\n\n\n<p>The main thing that will be used in this tutorial is a particle system that will simulate snowing. Click the <em>Create<\/em> button from the left menu and choose <em>Effects-&gt;Particle System<\/em>. Leave the default particles, since they already look like \u2018snowflakes\u2019, but you can download one of the many packs that offers different particles from the Asset Store.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"379\" height=\"167\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-5.png\" alt=\"\" class=\"wp-image-77469\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>You will, however, slightly alter the properties of the particle system to make it look more like a snowing effect. Set the Y coordinate of the system to be located higher than the plane and also rotate it on the X axis, to have the particles \u2018fall\u2019. This is how the properties should look like (on the right side of the window):<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"341\" height=\"74\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-6.png\" alt=\"\" class=\"wp-image-77470\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The next step is to decrease the speed of the particles and their size, while also increasing the <em>Radius<\/em> property of the <em>Shape<\/em> in order to cover the whole plane. You can play around with these options to achieve the desired outcome.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"347\" height=\"471\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-7.png\" alt=\"\" class=\"wp-image-77471\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Now that the basic snowing effect is in place, you can move on to the more interesting part of the tutorial. One more thing to do is disabling the particle system to control whether it snows in the beginning or not. To do this, uncheck the box from the top-right.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"337\" height=\"51\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-8.png\" alt=\"\" class=\"wp-image-77472\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The first step towards calling the API and getting useful information is to inspect the documentation. Any API that you decide to use should have a documentation page or file that explains what parameters you should supply and what is the expected result.<\/p>\n\n\n\n<p>For the weather API that we are using, there are two parameters that should be sent: the ID of the city, which can be easily found by searching for that city on the website, and the API key that is received after creating an account. This is what a typical URI (Uniform Resource Identifier) would look like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">api.openweathermap.org\/data\/2.5\/weather?id=2172797&amp;APPID=88169749096b61e3b85398905927f53c<\/pre>\n\n\n\n<p>A URI is a string that identifies a resource \u2013 most commonly, a URL (Uniform Resource Locator), also knows as a web address.<\/p>\n\n\n\n<p>According to the documentation, this is what a typical response should look like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\"coord\":{\"lon\":139,\"lat\":35},\n  \"sys\":{\"country\":\"JP\",\"sunrise\":1369769524,\"sunset\":1369821049},\n  \"weather\":[{\"id\":804,\"main\":\"clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\n  \"main\":{\"temp\":289.5,\"humidity\":89,\"pressure\":1013,\"temp_min\":287.04,\"temp_max\":292.04},\n  \"wind\":{\"speed\":7.31,\"deg\":187.002},\n  \"rain\":{\"3h\":0},\n  \"clouds\":{\"all\":92},\n  \"dt\":1369824698,\n  \"id\":1851632,\n  \"name\":\"Shuzenji\",\n  \"cod\":200}<\/pre>\n\n\n\n<p>By default, the data offered by the API is in JSON format. Most APIs will probably do the same, since the format is light-weight and understandable by most programming languages. If you get an XML or HTML response, the only difference should be the code for parsing the response into an object, but we will get to that later.<\/p>\n\n\n\n<p>By inspecting the response, we need to note what data we need to store for our purposes. The response contains a <strong>weather<\/strong> object, with a <strong>main<\/strong> field. This value contains one word that is used as the general description for the weather, so this is what we are mostly interested in.<\/p>\n\n\n\n<p>Now that we know what we need, it is time to go back to Unity and start coding. Right click in the file explorer (also known as <em>Project<\/em> tab or <em>Assets<\/em> window) from the bottom of the window and choose <em>Create-&gt;C# script<\/em> and name it <em>WeatherController<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"641\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-9.png\" alt=\"\" class=\"wp-image-77473\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Create an <em>Empty<\/em> object using the <em>Create <\/em>menu button in the <em>Hierarchy <\/em>window and attach this script to it. This can be done either by clicking the <em>Add Component <\/em>button in the <em>Inspector <\/em>and searching for your script or by clicking and dragging the script from the file explorer into the <em>Inspector<\/em>.<\/p>\n\n\n\n<p>Before implementing any functionality in the script, create the class that will hold the data that is received. Right-click on the solution explorer from the left side of Visual Studio or Mono Develop and add a new class to it. Name it <em>WeatherInfo<\/em>.<\/p>\n\n\n\n<p>In this class, you will add an <strong>id<\/strong> field and a <strong>name<\/strong> field. Even though these are not important for our purposes, they might be useful for debugging. You will also create another class called <strong>Weather<\/strong> in the same file (you can also create it in another file) containing an <strong>id<\/strong> field and a <strong>main<\/strong> field. Then, you will create a list of <strong>Weather<\/strong> objects in the <strong>WeatherInfo<\/strong> class. Furthermore, you will decorate both classes with the <strong>Serializable<\/strong> attribute, since you will need to deserialize the JSON response into them. This is what the file looks like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    [Serializable]\n      public class Weather\n      {\n          public int id;\n          public string main;\n      }\n      [Serializable]\n      public class WeatherInfo\n      {\n          public int id;\n          public string name;\n          public List&lt;Weather&gt; weather;\n      }<\/pre>\n\n\n\n<p>The list of <strong>Weather<\/strong> objects might seem weird, but if you go back to the JSON response example, you can see that the <strong>weather<\/strong> object is actually a list.<\/p>\n\n\n\n<p>Back in the <strong>WeatherController<\/strong> class, create a public field that allows a <strong>CityId<\/strong> input, and a constant string that will represent the API key.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">private const string API_KEY = \"88169749096b61e3b85398905927f53c\";\n  public string CityId;<\/pre>\n\n\n\n<p>Before being concerned with any other behavior, you\u2019ll create the method that will call the API. Name it <strong>GetWeather<\/strong>. It will return a <strong>WeatherInfo<\/strong> object. In this first example, use the <strong>HttpWebRequest<\/strong> class that is part of the .NET Framework. These namespaces are going to be used and the <strong>Assets<\/strong> namespace is used to include the <strong>WeatherInfo<\/strong> class:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using System.Net;\n  using System;\n  using System.IO;\n  using Assets;\n  private WeatherInfo GetWeather()\n      {\n          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format(\"http:\/\/api.openweathermap.org\/data\/2.5\/weather?id={0}&amp;APPID={1}\", CityId, API_KEY));\n          HttpWebResponse response = (HttpWebResponse)request.GetResponse();\n          StreamReader reader = new StreamReader(response.GetResponseStream());\n          string jsonResponse = reader.ReadToEnd();\n          WeatherInfo info = JsonUtility.FromJson&lt;WeatherInfo&gt;(jsonResponse);\n          return info;\n      }<\/pre>\n\n\n\n<p>The method creates a <strong>HttpWebRequest<\/strong> object based on the API URI that needs to be called to get the data. The <strong>String.Format<\/strong> method is used to easily introduce the parameters in the URI. The response is read from the <strong>HttpWebResponse<\/strong> into a string containing the full JSON object and then deserialized into the <strong>WeatherInfo<\/strong> object. To do this, use the <strong>JsonUtility<\/strong> class that is part of Unity, since introducing dependencies into a Unity project can be a bit more difficult. One important thing to note is that, unlike other JSON libraries, this one is case-sensitive when it comes to field names. Make sure that all the field names from your classes are the same as the ones from the JSON response.<\/p>\n\n\n\n<p>The next method to create is responsible for checking whether it is snowing or not in the city that was provided. You will also add another public field named <strong>SnowSystem<\/strong> and make sure that it\u2019s linked from the Unity editor. To do this, select the empty game object that was created earlier and drag and drop the particle system object into the slot.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"355\" height=\"79\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-10.png\" alt=\"\" class=\"wp-image-77474\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Here is the code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public GameObject SnowSystem;\n  \t\n     \n   public void CheckSnowStatus()\n      {\n          bool snowing = GetWeather().weather[0].main.Equals(\"Snow\");\n          if (snowing)\n              SnowSystem.SetActive(true);\n          else\n              SnowSystem.SetActive(false);\n      }<\/pre>\n\n\n\n<p>The <strong>CheckSnowStatus<\/strong> method verifies the value of the <strong>main<\/strong> field and performs an appropriate action on the particle system. This method will be called whenever we want to change the snowing effect. Since the weather API suggests not sending more than one request every ten minutes, you will create a counter for this. When the counter reaches zero, the code will call the API again and reset the value of the counter. This is what the script eventually looks like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public class WeatherController : MonoBehaviour\n  {\n      private const string API_KEY = \"88169749096b61e3b85398905927f53c\";\n      private const float API_CHECK_MAXTIME = 10 * 60.0f; \/\/10 minutes\n      public GameObject SnowSystem;\n      public string CityId;\n      private float apiCheckCountdown = API_CHECK_MAXTIME;\n      void Start()\n      {\n          CheckSnowStatus();\n      }\n      void Update()\n      {\n          apiCheckCountdown -= Time.deltaTime;\n          if (apiCheckCountdown &lt;= 0)\n          {\n              CheckSnowStatus();\n              apiCheckCountdown = API_CHECK_MAXTIME;\n          }\n      }\n      public void CheckSnowStatus()\n      {\n          bool snowing = GetWeather().weather[0].main.Equals(\"Snow\");\n          if (snowing)\n              SnowSystem.SetActive(true);\n          else\n              SnowSystem.SetActive(false);\n      }\n      private WeatherInfo GetWeather()\n      {\n          HttpWebRequest request = \n          (HttpWebRequest)WebRequest.Create(String.Format(\"http:\/\/api.openweathermap.org\/data\/2.5\/weather?id={0}&amp;APPID={1}\", \n           CityId, API_KEY));\n          HttpWebResponse response = (HttpWebResponse)request.GetResponse();\n          StreamReader reader = new StreamReader(response.GetResponseStream());\n          string jsonResponse = reader.ReadToEnd();\n          WeatherInfo info = JsonUtility.FromJson&lt;WeatherInfo&gt;(jsonResponse);\n          return info;\n      }\n  }<\/pre>\n\n\n\n<p>The constant floating-point variable, <strong>API_CHECK_MAXTIME<\/strong> holds the value of ten minutes, and an <strong>apiCheckCountdown<\/strong> variable that starts with the same value and will be used for counting that period of time. The code also calls <strong>CheckSnowStatus<\/strong> in the <strong>Start<\/strong> method, so the effect is checked when the game starts. For counting down the time, the code subtracts the <strong>Time.deltaTime<\/strong> value, which represents the time it took to complete the last frame.<\/p>\n\n\n\n<p>One problem with this solution is that it will significantly decrease the game speed by having to wait for the API response, which can sometimes take a few seconds. There are two solutions for this: using Unity\u2019s coroutines or .NET\u2019s async\/await.<\/p>\n\n\n\n<p>I will present the latter solution first, since it only takes a few changes in our existing code. To have this work in your project, go to the <em>File-&gt;Build Settings-&gt;Player<\/em> setting and change the <em>Scripting Runtime Version<\/em> to .NET 4.6.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"315\" height=\"104\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-11.png\" alt=\"\" class=\"wp-image-77475\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Back to the <em>WeatherController<\/em> script, we need to get the response from the request asynchronously. This means that the application will not be blocked while the response from the API is awaited. The changes only need to happen in the <strong>CheckSnowStatus<\/strong> and <strong>GetWeather<\/strong> methods. This is what they look like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public async void CheckSnowStatus()\n      {\n          bool snowing = (await GetWeather()).weather[0].main.Equals(\"Snow\");\n          if (snowing)\n              SnowSystem.SetActive(true);\n          else\n              SnowSystem.SetActive(false);\n      }\n      private async Task&lt;WeatherInfo&gt; GetWeather()\n      {\n          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format(\"http:\/\/api.openweathermap.org\/data\/2.5\/weather?id={0}&amp;APPID={1}\", CityId, API_KEY));\n          HttpWebResponse response = (HttpWebResponse)(await request.GetResponseAsync());\n          StreamReader reader = new StreamReader(response.GetResponseStream());\n          string jsonResponse = reader.ReadToEnd();\n          WeatherInfo info = JsonUtility.FromJson&lt;WeatherInfo&gt;(jsonResponse);\n          return info;\n      }<\/pre>\n\n\n\n<p>To be able to use the <strong>async<\/strong> functionality, the following namespace will be used:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using System.Threading.Tasks;<\/pre>\n\n\n\n<p>The most important change is that the <strong>request.GetResponse()<\/strong> was changed to <strong>request.GetResponseAsync()<\/strong>. Consequently, <strong>GetWeather<\/strong> method must be marked as <strong>async<\/strong>, since it performs an awaited operation, and made to return a <strong>Task&lt;WeatherInfo&gt;<\/strong> object instead of a <strong>WeatherInfo<\/strong> object. It is also the case for the <strong>CheckSnowStatus<\/strong> method, which now needs to wait for <strong>GetWeather<\/strong>. If you are not familiar with asynchronous programming and would like to learn more, <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/async\">this article<\/a> can be a good start.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-using-coroutines\">Using Coroutines<\/h2>\n\n\n\n<p>An alternative to this is to use Unity\u2019s coroutines. In the current case, it might be the most viable option. The difference between coroutines and asynchronous programming is that coroutines run for multiple frames, while \u2018awaited\u2019 methods are running in another thread. If you plan to send a web request for something like payment processing, when you wouldn\u2019t have the actual game running, asynchronous programming could work fine. For our purposes, when we call the API while many other things could happen, we should use coroutines.<\/p>\n\n\n\n<p>Starting with the <strong>GetWeather<\/strong> method, there are a few changes that need to be made. To use coroutines, we will use Unity\u2019s <strong>UnityWebRequest<\/strong> class, instead of .NET\u2019s <strong>HttpWebRequest<\/strong>. The code will wait for the response to be received, and then will convert it from JSON to an actual object the same way it did in the previous example.<\/p>\n\n\n\n<p>The main problem with coroutines is that they cannot return an actual value, since their return type must be <strong>IEnumerator<\/strong>. There are a few ways to work around this. The one used in this example has a lambda as a parameter for the <strong>GetWeather<\/strong> method and calls it after the response is processed.<\/p>\n\n\n\n<p>This is the modified method:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">IEnumerator GetWeather(Action&lt;WeatherInfo&gt; onSuccess)\n      {\n          using (UnityWebRequest req = UnityWebRequest.Get(String.Format(\"http:\/\/api.openweathermap.org\/data\/2.5\/weather?id={0}&amp;APPID={1}\", CityId, API_KEY)))\n          {\n              yield return req.Send();\n              while (!req.isDone)\n                  yield return null;\n              byte[] result = req.downloadHandler.data;\n              string weatherJSON = System.Text.Encoding.Default.GetString(result);\n              WeatherInfo info = JsonUtility.FromJson&lt;WeatherInfo&gt;(weatherJSON);\n              onSuccess(info);\n          }\n      }<\/pre>\n\n\n\n<p>One important aspect is using the <strong>yield<\/strong> keyword, which is the point where the method will be resumed from the next frame. After sending the request, a while loop makes sure that the response arrived before continuing with any other action. After converting the result, it calls the <strong>onSuccess<\/strong> lambda which will further process the data.<\/p>\n\n\n\n<p>The method supplied as the parameter for <strong>GetWeather<\/strong> is <strong>CheckSnowStatus<\/strong>. To make it suitable for this, add a parameter of the type <strong>WeatherInfo<\/strong> to it. This object is used to check the snow status.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public void CheckSnowStatus(WeatherInfo weatherObj)\n      {\n          bool snowing = weatherObj.weather[0].main.Equals(\"Snow\");\n          if (snowing)\n              SnowSystem.SetActive(true);\n          else\n              SnowSystem.SetActive(false);\n      }<\/pre>\n\n\n\n<p>As the last part, we need to start the coroutine. This will happen from the <strong>Start<\/strong> and <strong>Update<\/strong> methods:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void Start()\n      {\n          StartCoroutine(GetWeather(CheckSnowStatus));\n      }\nvoid Update()\n      {\n          apiCheckCountdown -= Time.deltaTime;\n          if (apiCheckCountdown &lt;= 0)\n          {\n              apiCheckCountdown = API_CHECK_MAXTIME;\n              StartCoroutine(GetWeather(CheckSnowStatus));\n          }\n}\n<\/pre>\n\n\n\n<p>This is the result of all the work that we have done once you run the game:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"767\" height=\"484\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/03\/word-image-12.png\" alt=\"\" class=\"wp-image-77476\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n\n\n\n<p>Calling a RESTful API in the context of a game might raise different problems than in other types of applications. It is important to choose the right method, depending on what you are trying to achieve, since games could be impacted more drastically by things such as memory leaks or blocked threads. A good way to test for such issues is to use the Unity Profiler, which can be opened from <em>Window-&gt; Profiler<\/em>; this tool offers insight into how much resources are used by each part of your game.<\/p>\n\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: Calling RESTful APIs in Unity3D<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. How do I call a REST API in Unity3D?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Use UnityWebRequest in a coroutine. Example: IEnumerator GetData() { using var request = UnityWebRequest.Get(&#8220;https:\/\/api.example.com\/data&#8221;); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { Debug.Log(request.downloadHandler.text); } else { Debug.LogError(request.error); } } Start the coroutine with StartCoroutine(GetData()). For POST requests with JSON, use UnityWebRequest.Post(url, jsonString) with a DownloadHandlerBuffer and UploadHandlerRaw with Content-Type set to application\/json.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. What is the difference between coroutines and threads for Unity API calls?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Coroutines run on Unity&#8217;s main thread and integrate naturally with the game loop &#8211; yield return pauses execution until the next frame or operation completes. They cannot truly run in parallel but avoid blocking the frame update. Threads run in parallel on separate CPU threads but cannot directly access Unity&#8217;s API (GameObject, Transform, UI) from a background thread &#8211; you must marshal results back to the main thread using a dispatcher pattern or Task.Run with ConfigureAwait(false) and then invoke Unity APIs back on the main thread. For simple API calls, coroutines are simpler; for CPU-heavy operations alongside API calls, threads are more appropriate.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. How do I POST JSON data to a REST API from Unity3D?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Build your JSON string (manually or with JsonUtility.ToJson(yourObject)). Create a UnityWebRequest: var request = new UnityWebRequest(url, &#8220;POST&#8221;); byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonString); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader(&#8220;Content-Type&#8221;, &#8220;application\/json&#8221;); yield return request.SendWebRequest(); This sends the JSON body and waits for the response. Unity&#8217;s built-in JsonUtility handles simple object serialisation; for complex JSON (nested objects, arrays), consider Newtonsoft.Json via the Unity Package Manager.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">4. How do I handle authentication headers in Unity UnityWebRequest?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Set headers before sending: request.SetRequestHeader(&#8220;Authorization&#8221;, &#8220;Bearer &#8221; + accessToken); or for Basic auth: request.SetRequestHeader(&#8220;Authorization&#8221;, &#8220;Basic &#8221; + Convert.ToBase64String(Encoding.ASCII.GetBytes(username + &#8220;:&#8221; + password))). Store credentials in a ScriptableObject or PlayerPrefs &#8211; never hardcode credentials in source files. For OAuth flows, store the access token obtained from an initial login request and include it in subsequent API calls.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Call REST APIs from Unity3D games using UnityWebRequest and coroutines. Covers GET and POST requests, handling async HTTP responses in Unity&#8217;s coroutine system, and choosing between threads and coroutines for API calls.&hellip;<\/p>\n","protected":false},"author":316106,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":true,"footnotes":""},"categories":[143538],"tags":[],"coauthors":[47840],"class_list":["post-77467","post","type-post","status-publish","format-standard","hentry","category-dotnet-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/316106"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=77467"}],"version-history":[{"count":11,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77467\/revisions"}],"predecessor-version":[{"id":109785,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77467\/revisions\/109785"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=77467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=77467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=77467"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=77467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}