Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

Unityで地図を表示してみる

こんにちは。 今回アドベントカレンダー初参加な@QBMK_IQUと言います。 現在モバイルファクトリーでサーバーサイドエンジニアとして働いています。

これは モバイルファクトリー Advent Calendar 2018 18日目の記事です。 昨日は@mizuki_rさんのモバイルファクトリー在籍中に開発したOSSの振り返りでした。

はじめに

モバイルファクトリーは位置情報を使ったアプリである、ステーションメモリーズ!(通称駅メモ!)を提供しております。 僕個人的にはUnityに興味があり勉強会に参加したり、趣味で実装したりしています。

では、Unityで地図を表示するにはどうすればいいのか?と思ったので実装してみます。

また、Unityには多くのアセットが販売されていることや、Unityに対応したSDKもあることも魅力なので、地図系のアセットやSDKの紹介もしようと考えています。

Unityで地図を表示する実装

今回はGoogle Mapを利用しようと思います。

今回の目的としては単純にとある地点を中心とした地図を表示したいだけなので、方針としては、Google Static Maps APIを利用して地図画像を取得し、取得した画像をUnity上のオブジェクトに貼り付ける方針で実装してみます。

APIキーを取得する

Google Static Maps APIが含まれるGoogle Maps APIを利用するためにはAPIキーが必要です。 ですので、まずはAPIキーを取得します。

Google Maps Platformにアクセスします。 Googleアカウントでログインし、右上の「スタートガイド」か「使ってみる」をクリックします。

どのAPIを有効にするかチェックする所があります。今回は全部チェックをいれました。

「+Create a new project」を選択し、分かりやすい名前をつけます。

請求先情報を登録していきます。

請求先情報が登録されると、APIの有効化に移ります。 「次へ」をクリックします。

これでAPIを取得できました。

使用料に関しては価格表で確認することができます。 今回使っているGoogle Static Maps APIは月10万回の表示までは無料です。 個人や研究目的くらいの使用量ならば、ほぼ超えることはないと思うので安心ですね。

地図を取得し貼り付ける実装

まずは、貼り付けるimageを用意します。 ヒエラルキー上で右クリックし、「UI」→「Image」で追加します。

次にスクリプトの用意です。 以下のようなスクリプトを追加します。

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

public class DrawGoogleMap : MonoBehaviour {
    public float lat = 35.6259034f;
    public float lng = 139.7268499f;
    public string key = null;
    public int zoom = 15;

    // Google Maps Embed API
    string Url = @"https://maps.googleapis.com/maps/api/staticmap?";

    // Use this for initialization
    void Start () {
        Build ();
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    public void Build(){

        // 中心座標 
        Url += "center=" + lat + "," + lng;

        // ズームレベル
        Url += "&zoom=" + zoom;

        // 地図画像のサイズ
        Url += "&size=480x480";

        if (key != null && key.Length != 0) {
            Url += "&key=" + key;
        }

        Url = Uri.EscapeUriString(Url);
        StartCoroutine(Download(this.Url, tex => addSplatPrototype(tex)));
    }

    /// GoogleMapsAPIから地図画像をダウンロードする
    IEnumerator Download(string url, Action<Texture2D> callback) {
        var www = new WWW(url);
        yield return www; // Wait for download to complete

        callback(www.texture);
    }

    /// imageにテクスチャを貼り付ける
    public void addSplatPrototype(Texture2D tex) {
        GetComponent<Image> ().sprite = Sprite.Create(tex, new Rect(0,0,tex.width,tex.height), Vector2.zero);
    }
}

このスクリプトを、先程追加したimageのコンポーネントに追加します。 そして、keyの部分に取得したAPIキーを入力します。

動作

再生ボタンを押して実行すると、上記の画像のように地図を表示することができました。

地図系のアセットやSDKの紹介

Unityのアセットストアでは数多くのアセットを売っており、それらを利用することで開発者は表現の幅を広げたり、開発工数の短縮を行うことができます。

また、Unity自体がメジャーになってきたので、様々なサービスがUnity用のAPIやSDKを提供している場合もあります。 ここでは、そういったSDKやアセットの中から地図に関連したものを紹介していきます。

Google Maps Platform

cloud.google.com

Googleは2018年3月に、ゲーム開発者に向けた「Google Maps API」での「Googleマップ」のリアルタイムデータの提供とUnityのゲームエンジンとの統合を発表しています。 Googleマップ上の建造物、道路、公園などのデータをUnityのGameObjectsとして使え、開発者はこれらのデータにテクスチャやスタイルを追加して使うことで、ゼロからゲームの世界を設計せずに済むそうです。 こちらのゲームへのサービスは、今回使ったAPIとは別軸の有料サービスとなっていて、詳しくは上記URLから問い合わせる必要があります。

MapBox for unity

www.mapbox.com

MapBoxではただ地図を表示するだけでなく、Mapbox Studioを使って表示のスタイルを細かくカスタマイズできたり、3Dの町並みを作ってUnityで利用できたりします。 こちらはMAU5万までの無料プランからアクセス数に応じた有償プランがあります。

api-sdk.navitime.co.jp

こちらはゲームアプリで地図を使った画面を作成することのできるSDKです。 Unityに対応したSDKもあり、ゲーム向けにデフォルメされたテクスチャや2D、3D、航空写真表示など用途に合わせた日本国内の地図表示を行うことができます。 詳しくは問い合わせる必要があるようです。

WRLD Unity SDK

www.wrld3d.com

こちらは地形生成系のアセットです。 地図データをAPIで取得し、Unity上でMeshを生成してゲームやアプリなどで利用することができます。 こちらはMAU6万までの無料プランからアクセス数に応じた有償プランがあります。

GoMap

assetstore.unity.com

こちらも地形生成系のアセットです。 特定の地点およびその周辺の地形を生成する事ができます。

最後に

今回行った地図を表示するという一つの事を行うにしても、APIを使って自分で実装する、提供されているSDKを使う、販売されているアセットを使うなど様々な方法があります。

今回は既に提供されているGoogle Static Maps APIを利用しました。 また、SDKの提供・更新の終了やアセットストアから消える可能性、コストや機能など、目的やリスクを考えて企業のサービスとして地図を使いたいという場合は自前で地図サーバーやAPIを用意するという判断もアリだと思います。

Unityでは一つの機能を実装するにも様々な方法があります。 実現したいことの規模や必要な機能や運用期間や更新頻度やコストなど、状況にあった方法をいろいろと探してみるのも楽しいかと思います。

次はid:neshです。お楽しみに!!