Hi, welcome to the Iståke Locations API Unity tool! Thanks for getting the asset. This document will walk you through how to use the tool, and how to expand upon it in code to build up functionality for your game.
The most basic usage of this asset is through the Iståke Location input field. Drag the prefab into your scene, and your players will instantly be able to type in and select their location from over 4.8 million places in the world. You can either choose to save the resulting Location
object in Unity’s PlayerPrefs (the location ID is saved as a string, which you can use at a later stage to query the API again and get the full location data), or you can connect your own code to serialize the data or save it as part of your game.
Customise the look and feel of the input field to fit your game by editing the UI components that make up the prefab. The LocationInputField component also offers some level of customisation over the behaviour of the asset. And if there’s one part of the prefab you don’t like or want to replace, you can just delete it, the LocationInputField component is built robustly, so it should still work as expected.
Take a look at the options you have on the LocationInputField and LocationSaver components.
LocationInputField option | Behaviour |
---|---|
Max Number Of Options | The maximum amount of different suggestions that will be given to users upon looking up a location by name. |
Query Language | ISO 639-1 language code; the language in which the results of users’ queries will be displayed. Note that if you change this value, you might want to also translate the prefab’s UI (Input title, Placeholder and Error display objects). A number of common languages are provided as alternate prefabs under prefabs/localisations/ . |
Hide Suggestions When Unfocused | If this is set to false , the list of suggestions shown to users will be shown regardless of whether the input field is in focus. |
Always Show Suggestions On Mobile | Regardless of the previous option’s value, if this is set to true , suggestions will persist on Android and iOS platforms no matter what. |
No Selection Color | The colour that will be shown on the input field’s outline by default. |
Invalid Selection Color | The colour that will be shown when a user enters an invalid location name, or unfocuses the component without selecting a location first. |
Valid Selection Color | The colour that will be shown when a user enters a location name and selects one of the options. |
Error Color | The colour that will be shown when a network error prevents the input field from fetching data from the servers. |
Init On Awake | If this is unchecked, you need to make sure to call Init() on the LocationInputField yourself from a different MonoBehaviour. This is useful if you need to change the settings at runtime, for example. |
Persistent Location | A PersistentLocation element. By default, this will be the instance of LocationSaver on the GameObject, but you can override PersistentLocation to provide your own serialization logic for locations and use that instead. |
On Select | A UnityEvent that will fire upon the user selecting a valid location, along with the selected location. |
On Deselect | A UnityEvent that will fire upon the user cancelling and deleting a selected location. |
Loading Circle | A component that will be shown spinning when the backend is being queried. |
Suggestion Prefab | A prefab that will be spawned for each suggestion given to the player. By default, will be the Option prefab provided with the asset. |
Suggestion Container | The parent transform where Suggestion Prefabs will be spawned. |
Network Error Display | A GameObject that will be activated when network issues prevent locations from being searched. |
Gradient Overlay | A cosmetic image, displayed at the end of the input field to fade the text to white. |
Flag Display | A RawImage that will display the selected location’s flag once (if) it can be loaded. |
LocationSaver option | Behaviour |
---|---|
Player Prefs Key | The key that will be used to save selected locations in Unity PlayerPrefs. IF you have several location input fields, ensure that each uses a different key (unless the intended behaviour is that they all mirror the same location). |
Infer From GPS | Whether to attempt using the device GPS to find the closest location (town or city) when no value was previously saved by the player on scene load. Android & iOS platforms only. |
Gps Radius | The maximum distance, in kilometres, of the inferred location to the player’s device GPS coordinates. |
Gps Timeout | When using the GPS, how long to wait for the chip to find a set of coordinates before giving up, in seconds. |
To make the most out of the API, you’ll need to write your own C# code to connect the features with your game’s logic. Note that most of the functionality is documented in the source code as well.
Istaake.Locations.Model.APIInfo
classA wrapper around the current version, as given by the server. This class is declared within the Istaake.Locations.dll binaries.
Fields | Type | Description |
---|---|---|
Version |
string property |
Semantic version number; for example, 1.0.0-alpha . |
Istaake.Locations.Model.Country
classRepresents a country of the world. This class is declared within the Istaake.Locations.dll binaries.
Fields | Type | Description |
---|---|---|
Id |
string property |
A unique ID that represents the country. You can obtain a country’s full data by querying Istaake.Locations.LocationsUtility.GetCountry(id) with the country’s ID. |
Name |
string property |
The country’s name, localized to whatever language the data was queried for. |
CountryCode |
string property |
ISO 3166 Alpha-2 country code for the country. |
ContinentCode |
string property |
One of EU , NA , SA , AF , OC , AS or AN . |
ContinentName |
string property |
English name of the continent the country is on. Only given when querying full location information. |
FlagBitmap |
string property |
Base64 image of a 24x24 version of the country’s flag. Only given when querying full location information. |
FlagVector |
string property |
SVG code for a vector version of the country’s flag. Only given when querying full location information. |
Languages |
List<Language> property |
A list of the languages spoken in the country. Only given when querying full location information. |
Timezone |
Timezone property |
The timezone associated with the location. |
Istaake.Locations.Model.Language
classRepresents a spoken language. This class is declared within the Istaake.Locations.dll binaries.
Fields | Type | Description |
---|---|---|
EnglishName |
string property |
The English name of the language. |
NativeName |
string property |
The native name of the language. |
LanguageCode |
string property |
ISO 639-2 (3-character) code for the language. |
LanguageCodeShort |
string property |
ISO 639-1 (2-character) code for the language; note that certain languages do not have an ISO 639-1 representation, so if you’re aiming to support many locales, use the LanguageCode property instead. |
Istaake.Locations.Model.Location
classRepresents a location, i.e. a town or city. This class is declared within the Istaake.Locations.dll binaries.
Fields | Type | Description |
---|---|---|
Id |
string property |
A unique ID that represents the location. You can obtain a location’s full data by querying Istaake.Locations.LocationsUtility.GetLocation(id) with the location’s ID. |
Name |
string property |
The location’s name, localized to whatever language the data was queried for. |
RegionName |
string property |
The first-level administrative region in which the location is situated’s name, localized to whatever language the data was queried for. |
Country |
Country property |
The country the location is situated in. Note that the country data may be partial only, depending on how the data was queried. If you need the continent name, language information or flag, use full = true . |
Latitude |
decimal property |
The latitude of the location. |
Longitude |
decimal property |
The longitude of the location. |
GetDisplayString() |
string |
Returns a formatted string that can be used to display the location in text; for example, London, England, United Kingdom . Will adapt to locations that do not have a region or country name. |
Istaake.Locations.Model.Timezone
classRepresents a timezone. This class is declared within the Istaake.Locations.dll binaries.
Fields | Type | Description |
---|---|---|
Name |
string property |
The timezone’s formal name; for example, “Europe/Oslo” or “America/Chicago”. |
GmtOffset |
decimal property |
How many hours ahead or behind GMT the timezone is. |
DstOffset |
decimal property |
How many hours ahead or behind DST the timezone is. Generally, will be GmtOffset for timezones that do not follow summer time, and GmtOffset + 1 for timezones that do. |
CurrentTime |
DateTime property |
The current time in the timezone, at the time the data was queried. |
Istaake.Locations.LocationEvent
classA serializable version of UnityEvents with a single Location argument, meaning it can be displayed in an inspector in Unity.
Example (C#):
using Istaake.Locations;
using Istaake.Locations.Model;
using UnityEngine;
public class Test : MonoBehaviour {
/// The following event will be editable in the inspector
[SerializeField] LocationEvent onSelectLocation;
void Start(){
Location loc;
// ... obtain location from somewhere
onSelectLocation.Invoke(loc);// callback event
}
}
Istaake.Locations.CountryEvent
classA serializable version of UnityEvents with a single Country argument, meaning it can be displayed in an inspector in Unity.
Istaake.Locations.LocationsUtility
static classAn abstraction layer over Istaake.Locations.Api
and Istaake.Locations.Client
classes; note that you’re free to use those directly instead, but they’re not documented here, and LocationsUtility
is generally safer and easier to use. These functions are all asynchronous; they’ll return after getting data back from the servers. For ease of use, call them in async
contexts using await
. There’s plenty of examples of doing so in the source code provided.
Fields | Type | Description |
---|---|---|
Version |
static async string property |
API backend semantic version number; for example, 1.0.0-alpha . Before any calls into the API, make sure to check this property’s value first; null means there’s a problem accessing the server (most probably a network issue, i.e. the user’s device is offline). |
GetLocation(locationId, languageCode = "en", full = false) |
static async Location |
Returns the Location object that corresponds to the unique location ID. languageCode should be an ISO 639-1 language code for whatever language you wish to get information in. Set full to true if you require the continent name or data for the spoken languages and/or country flag; note that the request will take longer to process. |
GetCountry(countryId, languageCode = "en") |
static async Country |
Returns the Country object that corresponds to the unique country ID. languageCode should be an ISO 639-1 language code for whatever language you wish to get information in. Unlike GetLocation , this function will always give full flag/language/continent information for the country. |
Search(searchTerm, languageCode = "en", limit = 5, full = false) |
static async List<Location> |
Searches the database for up to limit locations given a search query searchTerm . languageCode should be an ISO 639-1 language code. Set full to true if you require the continent name or flag/language info; note however that the request will take significantly longer, especially if limit is high. |
Search(latitude, longitude, radius = 10, languageCode = "en", limit = 5, full = false) |
static async List<Location> |
Searches the database for up to limit locations within a radius of radius km around the latitude & longitude coordinates. languageCode should be an ISO 639-1 language code. Set full to true if you require the continent name, flag and language data; note however that the request can take significantly longer. |
Example (C#):
// in an async context...
// Obtain the first 10 locations for the search term "Oslo", in Norwegian
List<Location> locations = await LocationsUtility.Search("Oslo", "no", 10);
// Display the location names
foreach(Location loc in locations)
Debug.Log(loc.GetDisplayString());
// Get and print the country where London is situated
Country uk = (await LocationsUtility.Search("London"))[0].Country;
Debug.Log("London is in " + uk.Name);
Istaake.Locations.LocationSelector
classA driver class for the use case of typing location names and selecting one; see usage in LocationInputField
class.
Fields | Type | Description |
---|---|---|
LastError |
Exception property (read-only) |
The last error that happened when trying to obtain data or connect to the server; intended usage is to poll this value in Update to check whether anything happened. Usually these errors will not require you or the user to take any further action and are only provided for information purposes. null when everything is fine. |
Loading |
bool property (read-only) |
Whether a query is being processed; use to display a buffering indicator. |
Options |
List<Location> property (read-only) |
The location suggestions that have been returned as a result of the last query. |
OptionsLoadNumber |
int property (read-only) |
This value will be incremented anytime a new set of Options becomes available. You can use this to prevent re-loading the display every single frame, instead keeping track of what the OptionsLoadNumber value was when you last updated the UI, and comparing it to this field. |
Selected |
Location property (read-only) |
The selected location, or null . After a location has been selected, this field will be updated twice; once with the new selection, and once after obtaining more data about the location (flag, languages, etc). |
LocationSelector(maxNumberOfOptions = 5, queryLanguage = "en", persistentLocation = null, Action<Location> onSelectLocation = null |
void (constructor) | Use to setup the LocationSelector . maxNumberOfOptions is the maximum amount of suggestions shown at any time, queryLanguage the language in which suggestions will be returned, persistentLocation an optional PersistentLocation instance where locations will be saved and retrieved, onSelectLocation a callback invoked anytime Selected changes. |
LoadOptions(query) |
async void | Loads in a different set of suggestions, from a query string. The new locations will be loaded asynchronously, so you might prefer to poll Options and/or OptionsLoadNumber instead of waiting for this call to return. If called several times in a row, only the last call will be preserved (even if it returns before one of the previous calls). |
ResetOptions() |
void | Resets the suggestion list and clears the selected location. |
SetSelected(location) |
async void | Sets the selected location, and keeps it persistent through the PersistentLocation instance, if given. If the given location’s data is only partial, will load the full corresponding data (flag, languages, etc) and update Selected with the new data once available. |
Istaake.Locations.PersistentLocation
abstract classAn interface that you can override to provide an optional default location to a LocationSelector
instance, and that will receive a callback upon a new location being selected. See example implementation in LocationSaver
MonoBehaviour, which saves the selected location in a PlayerPrefs entry, and optionally provides the default (initial) location with the GPS coordinates of the device.
Fields | Type | Description |
---|---|---|
SetLocation(location) |
abstract void | Called when a location has been selected by the user, where parameter location is the newly selected location, or null . Override in implementation. |
GetDefaultLocation(languageCode) |
abstract async Location |
Called when loading the LocationSelector instance, intending to receive the location that will be displayed by default in the field (or null ). If saving the location in SetLocation() , the expected behaviour is that this function returns the saved location. |
Example (C#):
using Istaake.Locations;
using Istaake.Locations.Model;
using System.Threading.Tasks;
using UnityEngine;
/// Dummy implementation of PersistentLocation
public class ExamplePersistentLocation : PersistentLocation {
// Called when selecting a location
public override void SetLocation(Location location) {
// Simply log the selected location to the console
if(location == null)
Debug.Log("Deselected location.");
else
Debug.Log("Selected location: " + location.GetDisplayString());
}
// Called when deciding which location by default to display
public override Task<Location> GetDefaultLocation(string languageCode){
return Task.Run(async () => {
// Search a dummy location to display and return it.
// When loading the Scene, the initial displayed location will therefore always be Oslo.
return (await LocationsUtility.Search("Oslo", languageCode, 1))[0];
});
}
}
Istaake.Locations.LocationInputField
MonoBehaviourA script that drives the Iståke Location Input Field prefab. Uses a LocationSelector
as a driver to search and select a location from a list. Please refer to the Basic Usage section above for a rundown of the available inspector options when using this script.
Fields | Type | Description |
---|---|---|
SelectedLocation |
Location property (read-only) |
The location that has been selected by the user; may be null . Subscribe to onSelect and onDeselect to receive callbacks whenever this value changes. |
SelectedLocationId |
string property (read-only) |
SelectedLocation 's id, provided as convenience. May be null . |
Init(language, maxNumberOfOptions = 5) |
void (initializer) | Call this once in Awake() or Start() if you’ve set Init On Awake to false in the inspector. This is useful if you want to be able to change the query language at runtime. |
Init() |
void (initializer) | Call this once in Awake() or Start() , if you’ve set Init On Awake to false. If you’re calling this directly (rather than the overload above), you’re probably better off just setting Init On Awake and letting Unity call this function in Awake() . |
OnValueChange(val) |
void callback | Don’t call this directly unless you’ve removed the Unity UI Input Field from the Game Object; this function will be called by the Unity UI Input Field whenever the text value is modified. |
OnEndEdit(val) |
void callback | Don’t call this directly unless you’ve removed the Unity UI Input Field from the Game Object; this function will be called by the Unity UI Input Field whenever the component becomes unfocused. |
Istaake.Locations.LocationSaver
MonoBehaviourThe default PersistentLocation
implementation. Will save selected locations in PlayerPrefs, and optionally select the device’s GPS location by default if no location was selected by the user. Please refer to the Basic Usage section above for a rundown of the available inspector options when using this script.
Fields | Type | Description |
---|---|---|
SetLocation(location) |
override void | Will save the selected location’s ID in a PlayerPrefs entry, using the key set in the inspector. |
GetDefaultLocation(languageCode) |
override async Location |
If a location has been saved in PlayerPrefs entry, loads the location’s full information in the selected language and returns it. If no location was saved for this LocationSaver key, can optionally attempt to provide the closest physical location to the player using the device GPS coordinates (Android or iOS only). |
Istaake.Locations.LocationsTest
MonoBehaviourEditor-only component. Drag to a GameObject and press play in your Scene to call each of the API functions once and view some of the results in the console. Use as a set of examples as to how to use the LocationsUtility
functions. Once you’re done, remember to remove the component from your Scene. As it’s set up, the tests will only be run in editor; open the source code and remove the #if UNITY_EDITOR
, #else
and #endif
directives to enable running the tests in non-editor builds, if needed.
Depending on your use case, you might run into a situation where you want to call the API endpoints directly without using the Unity C# client. For example, if you’re allowing players to select their locations within the game and then send it to a server, it’s a good idea to check that the given location ID is valid in an attempt to sanitize backend inputs.
The HTTP request endpoints are fully documented following the OpenAPI 3.0 specification here. Execute a GET
request into one of the routes to get location data directly from your backend.
Example (PHP):
// Get user's location ID from POST request parameters
if(!isset($_POST["location"])) die("Invalid location");
$locationID = $_POST["location"];
// Get location data from Iståke locations API
$url = "https://jonathan-kings.com/games-locations-api/api/v1/locations/$locationID";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
if($output === false){
echo "Curl error ".curl_errno($ch).": ".curl_error($ch);
curl_close($curl);
die();
}
curl_close($curl);
// Check that the location is valid
$location = json_decode($output);
if(!isset($location->id) || $location->id != $locationID)
die("Invalid location");
// Extract information for the location
echo "User is in ".$location->name.", ".$location->country->name.".";
// Proceed...
The API is built on top of GeoNames under CC BY 4.0 attribution license, REST Countries under MPL 2.0 license, and GoSquared under MIT license.
The Unity C# client uses RestSharp under Apache 2.0 license, Json.NET and JsonSubTypes under MIT license. The C# client was built using the openapi-generator toolset.
The Unity C# code and binaries provided as part of the asset are provided under standard copyright. All rights reserved (Iståke 2020). Please be so kind as to not redistribute, except internally. You’re free to use and modify the code if you or one of the members of your team has purchased the asset from the Unity Asset Store.
If you find any issues or bugs with the asset or API or would like to request for a new feature to be implemented, or generally have any questions that this document doesn’t already answer, please send an email to istaakestudio@gmail.com.