fake_coder2's tech blog

偽物のほうが本物よりも本物だ

【Unity】初心者がUnity Editor上で地図を表示する

GoogleのMaps Static APIを使用してUnity Editor上で地図を表示してみる。

1.環境

PC

MacBook Air M1

Unity

バージョン:2019.4.20f1

2.コード全容

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;

public class GoogleMapTile : MonoBehaviour
{
    // Google Maps API Staticmap URL
    string API_KEY = "自分のAPIキー";    
    string STATIC_MAP_URL = "https://maps.googleapis.com/maps/api/staticmap?";

    // オプションでURLに付加するパラメータ
    public string center = "";
    public string zoom = ""; 
    public int size;
    public string maptype = "";
    public string markers = "";
    public string format = "";
    public string sensor = "";

    // centerに指定するためのもの //
    // 経度
    public float longitude ;
    // 緯度
    public float latitude;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(getStaticMap());
    }

    // Update is called once per frame
    void Update()
    {
        // ただ固定の地図を表示するだけだから特になし
    }

    IEnumerator getStaticMap()
    {
        var req = UnityWebRequestTexture.GetTexture(STATIC_MAP_URL + 
                                                   "center=" + longitude + "," + latitude + 
                                                   "&zoom=" + zoom + 
                                                   "&format=" + format + 
                                                   "&sensor=" + sensor + 
                                                   "&size=" + size + "x" + size + 
                                                   "&maptype=" + maptype +
                                                   "&key=" + API_KEY);
        // リクエスト実行
        yield return req.SendWebRequest();
 
        if (req.error == null)
        {
            GetComponent<Renderer>().material.mainTexture = ((DownloadHandlerTexture)req.downloadHandler).texture;
        }
    }
}

3.実行結果

なぜかデフォルトだと地図が180度回転して表示されるため、InspectorウィンドウでTransform.Rotation.Yを180に設定している。Transform.Position.Yを10に設定しているのは地図を大きく見せるため。
※ 画像ではGoogleMapTileスクリプトが複数あるが1つあればいい。

f:id:captaindream0502:20211113191650p:plain
キャプチャ1

スクリプト内でpublic宣言した変数はInspectorウィンドウで任意のパラメータを設定することができる(赤枠内)。
今回は画像の通りにパラメータを設定して実行。

f:id:captaindream0502:20211113193952p:plain
キャプチャ2

4.コード解説

ポイントの部分だけをかいつまんで解説する。

URLの指定

Google Maps Static APIの利用にはGoogle Cloud Platform(GCP)へのアカウント登録が必要である。登録後、自分のAPIキーを確認し、API_KEYの部分に代入する。

// Google Maps API Staticmap URL
string API_KEY = "自分のAPIキー";    
string STATIC_MAP_URL = "https://maps.googleapis.com/maps/api/staticmap?";

経度・緯度について

経度、緯度はcenterの値として使用する。地図の取得には経度、緯度の情報が必要不可欠である。今回はGoogle Maps API Staticmap公式ページの経度37、緯度-122をそのまま使用した(面倒だから小数点以下は切り捨てた)。
国、あるいは都市によっては、centerにその名称を指定する方法でも地図の取得は可能なようだ。

/* centerに指定するためのもの */
// 経度
public float longitude ;
// 緯度
public float latitude;

非同期処理での実行

StartCoroutine(class in UnityEngine.MonoBehaviour):Unityの公式Scripting API
コルーチンの開始。非同期処理(≒並行処理)のことを言うらしい。IEnumeratorで定義された関数が、非同期処理として動かすことができる。

StartCoroutine(getStaticMap());

リクエストの定義

UnityWebRequestTexture(class in UnityEngine.Networking):Unityの公式Scripting API
ネットワークと通信して画像を取得するくらいのニュアンス。GetTextureはTextureの作成。

var req = UnityWebRequestTexture.GetTexture(STATIC_MAP_URL + 
                                           "center=" + longitude + "," + latitude + 
                                           "&zoom=" + zoom + 
                                           "&format=" + format + 
                                           "&sensor=" + sensor + 
                                           "&size=" + size + "x" + size + 
                                           "&maptype=" + maptype +
                                           "&key=" + API_KEY);

取得した画像をタイルテクスチャに設定

GameObject.GetComponent:Unityの公式Scripting API
このスクリプトがアタッチされているゲームオブジェクトのコンポーネント(Inspectorに表示される各種設定)を取得。今回はPlaneにWEBリクエストで取得した画像をタイルテクスチャとして設定する。

GetComponent<Renderer>().material.mainTexture = ((DownloadHandlerTexture)req.downloadHandler).texture;

 

本来は位置情報を組み合わせてユーザの位置とともに地図を更新する処理を組みたいところだが、なかなか難易度が高く、まずは固定地図の表示ということでやってみた。

以上