本日はMapsSDK for Unity応用枠です。
MapsSDK for Unityでは[MapPin]と呼ばれる機能があり、地図上の任意の座標にオブジェクトを配置することができます。
これはMapsSDKの[MapPinExamles]というサンプルで提供されています。
MapPinの仕組みとしては[MapPin]を描画するための[MapPinLayer]コンポーネントと、SCVデータから座標を読み込み配置する[MapPinProvider]コンポーネントで実現しています。
今回は[MapPinProvider]コンポーネントを改造して任意のタイミングでピンをさせるようにします。
〇任意のタイミングでピンを立てる
[MapPinProvider]コンポーネントではAwake関数でシーン実行時にピン立が実行されます。
void Awake() { ... }
①Awake関数をパブリックな変数にします。
public void PinAwake() { ... }
今回はPinAwakeと関数を作りました。
この作業によって自動的に実行されなくなり、外部のクラスから呼び出す必要があります。
次にピンを立てるcsvを任意で変更できるように変数を改造します。
②変数をPublicにします。
public class MapPinProvider : MonoBehaviour { [SerializeField] private MapPinLayer _mapPinLayer = null; public MapPin _mapPinPrefab = null; public TextAsset _mapPinLocationsCsv = null; ...
以上で[MapPinProvider]コンポーネントの改造が終わりました。次に任意のタイミングで呼び出せるように外部クラスを作ります。
今回は前回作成した山手線ツアーと合わせてツアー開始時に山手線の各駅にピンがたつようにします。
③[YamanoteTour]クラスにパブリックな変数として[MapPinProvider]、[MapLayer]を作成します。
public MapPinProvider _mapPinProvider; public MapLayer _mapLayer;
④山手線ツアーの発火とピンを立てるのを同期させるためTourStart関数に以下の処理を加えます。
public void TourStart() { _isActive = true; _mapPinProvider._mapPinLocationsCsv = _tourCSV;//追加 StartCoroutine(PinCreate());//追加 StartCoroutine(RunTour()); }
⑤次にピンを生成するコルーチンを作成します。
private IEnumerator PinCreate() { yield return new WaitForSeconds(11.0f); _mapPinProvider.PinAwake(); }
ここでは山手線ツアーが始まり十分マップを読み込んだと判断される11秒待ってPinAwakeを呼び出しています。
以上で任意のタイミングでピンを立てることができるようになりました。
最後に任意のタイミングでピンを削除します。
⑥TourEnd関数に以下の処理を加えます。
public void TourEnd() { _isActive = false; _mapLayer.enabled = false;//追加 }
[MapLayer]をディアクティブにすることでマップピンを削除します。
以上で任意のタイミングでマップピンを立て、削除できるようにしました。
〇スクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; using Microsoft.Maps.Unity; using Microsoft.Geospatial; using Unity.VisualScripting; public class YamanoteTour : MonoBehaviour { public MapPinProvider _mapPinProvider; public MapLayer _mapLayer; //Defalt Location 37.7,137.9,4.8 [SerializeField] private TextAsset _tourCSV; private static readonly List<MapScene> MapScenes = new List<MapScene> { // TokyoStation -> Yurakucho new MapSceneOfLocationAndZoomLevel(new LatLon(35.681382, 139.76608399999998), 16.8f), // Yurakucho->shinbashi new MapSceneOfLocationAndZoomLevel(new LatLon(35.675069, 139.763328), 17.3f), // Shinbashi new MapSceneOfLocationAndZoomLevel(new LatLon(35.665498 , 139.75964), 16.0f), // Hamamatucho new MapSceneOfLocationAndZoomLevel(new LatLon(35.655646, 139.756749), 17.0f), // Tamachi new MapSceneOfLocationAndZoomLevel(new LatLon(35.645736 , 139.74757499999998), 17.0f), // TakanawaGateway // Shinagawa new MapSceneOfLocationAndZoomLevel(new LatLon(35.630152, 139.74044000000004), 16.15f), // Osaki new MapSceneOfLocationAndZoomLevel(new LatLon(35.6197, 139.72855300000003), 17.0f), // Gotanda new MapSceneOfLocationAndZoomLevel(new LatLon(35.626446, 139.72344399999997), 17.5f), // Meguro new MapSceneOfLocationAndZoomLevel(new LatLon(35.633998 , 139.715828), 17.5f), // Ebisu new MapSceneOfLocationAndZoomLevel(new LatLon( 35.64669, 139.710106), 17.5f), // Shibuya new MapSceneOfLocationAndZoomLevel(new LatLon(35.658517, 139.70133399999997), 15f), // Harajuku new MapSceneOfLocationAndZoomLevel(new LatLon(35.670168 ,139.70268699999997),17f), // Yoyogi new MapSceneOfLocationAndZoomLevel(new LatLon(35.683061,139.702042),17f), // Shinjuku new MapSceneOfLocationAndZoomLevel(new LatLon(35.690921,139.70025799999996),17f), // ShinOkubo new MapSceneOfLocationAndZoomLevel(new LatLon(35.701306,139.70004399999993),17f), // Takadanobaba new MapSceneOfLocationAndZoomLevel(new LatLon(35.712285, 139.70378200000005),17f), // Mejiro new MapSceneOfLocationAndZoomLevel(new LatLon(35.721204 ,139.706587),17f), // Ikebukuro new MapSceneOfLocationAndZoomLevel(new LatLon(35.728926 ,139.71038),17f), // Otuka new MapSceneOfLocationAndZoomLevel(new LatLon(35.731401 ,139.72866199999999),17f), // Sugamo new MapSceneOfLocationAndZoomLevel(new LatLon(35.733492,139.73934499999996),17f), // Komagome new MapSceneOfLocationAndZoomLevel(new LatLon(35.736489,139.74687500000005),17f), // Tabata new MapSceneOfLocationAndZoomLevel(new LatLon(35.738062 ,139.76085999999998),17f), // Nishi Nippori new MapSceneOfLocationAndZoomLevel(new LatLon(35.732135,139.76678700000002),17f), // Nippori new MapSceneOfLocationAndZoomLevel(new LatLon(35.727772 ,139.770987),17f), // Uguisudani new MapSceneOfLocationAndZoomLevel(new LatLon(35.720495 ,139.77883700000007),17f), // Ueno new MapSceneOfLocationAndZoomLevel(new LatLon(35.713768,139.77725399999997),17f), // Okachimachi new MapSceneOfLocationAndZoomLevel(new LatLon(35.707438 ,139.774632),17f), // Akihabara new MapSceneOfLocationAndZoomLevel(new LatLon(35.698683 ,139.77421900000002),17f), // Kanda new MapSceneOfLocationAndZoomLevel(new LatLon(35.69169 ,139.77088300000003),17f) }; [SerializeField] private MapRenderer _map = null; private bool _isActive; private void Awake() { Debug.Assert(_map != null); } public void TourStart() { _isActive = true; _mapPinProvider._mapPinLocationsCsv = _tourCSV; StartCoroutine(PinCreate()); StartCoroutine(RunTour()); } public void TourEnd() { _isActive = false; _mapLayer.enabled = false; } private IEnumerator PinCreate() { yield return new WaitForSeconds(11.0f); _mapPinProvider.PinAwake(); } private IEnumerator RunTour() { yield return new WaitForSeconds(5.0f); while (_isActive) // loop the tour as long as we are running. { foreach (var scene in MapScenes) { yield return _map.SetMapScene(scene); yield return new WaitForSeconds(3.0f); Debug.Log(_isActive); if (!_isActive) { break; } } } } }