using System.Collections.Generic; using System.Linq; using UnityEngine; public class TurnByTurnNavi:MonoBehaviour { public string googleAPIKey; public string fromPlace = "Los Angeles"; // For debugging purposes public string toPlace = "Hollywood"; public float successDistanceKM = 0.02f; public float leftRouteDistanceKM = 0.1f; private int pointIndex; private int stepIndex; private OnlineMapsGoogleDirectionsResult.Route route; private List steps; private OnlineMapsLocationService locationService; private bool isFinished; private bool hasRoute; private OnlineMapsDrawingLine routeLine; private void OnGUI() { if (GUILayout.Button("Find route")) { OnlineMapsGoogleDirections.Find(new OnlineMapsGoogleDirections.Params(locationService.position, toPlace) { key = googleAPIKey }).OnComplete += OnGoogleDirectionsComplete; OnlineMapsControlBase.instance.OnMapClick += OnMapClick; } } private void OnGoogleDirectionsComplete(string response) { OnlineMapsGoogleDirectionsResult result = OnlineMapsGoogleDirections.GetResult(response); if (result == null || result.routes.Length == 0) { Debug.Log("Something wrong"); Debug.Log(response); return; } route = result.routes[0]; steps = route.legs.SelectMany(l => l.steps).ToList(); if (routeLine == null) { routeLine = new OnlineMapsDrawingLine(route.overview_polylineD, Color.red, 3); OnlineMaps.instance.AddDrawingElement(routeLine); } else { routeLine.points = route.overview_polylineD; OnlineMaps.instance.Redraw(); } pointIndex = 0; stepIndex = 0; isFinished = false; hasRoute = true; locationService.OnLocationChanged += OnLocationChanged; Debug.Log(steps[0].string_instructions); } private void OnLocationChanged(Vector2 vector2) { if (!hasRoute || isFinished) return; OnlineMapsGoogleDirectionsResult.Step currentStep = steps[stepIndex]; Vector2 prevPoint = currentStep.polyline[pointIndex]; Vector2 nextPoint = currentStep.polyline[pointIndex + 1]; // Check the distance to the next point if (OnlineMapsUtils.DistanceBetweenPoints(locationService.position, nextPoint).magnitude > successDistanceKM) { pointIndex++; if (pointIndex == currentStep.polyline.Length - 1) { stepIndex++; pointIndex = 0; if (stepIndex == steps.Count) { isFinished = true; Debug.Log("Finished"); return; } Debug.Log(steps[stepIndex].string_instructions); } } // Check whether the user is on the route if (OnlineMapsUtils.DistanceBetweenPoints(locationService.position, OnlineMapsUtils.NearestPointStrict(locationService.position, prevPoint, nextPoint)).magnitude > leftRouteDistanceKM) { // Check the following points. Perhaps something was skipped. bool isFound = false; for (int si = stepIndex; si < steps.Count; si++) { for (int pi = pointIndex; pi < steps[si].polyline.Length - 1; pi++) { prevPoint = steps[si].polyline[pi]; nextPoint = steps[si].polyline[pi + 1]; float dist = OnlineMapsUtils.DistanceBetweenPoints(locationService.position, OnlineMapsUtils.NearestPointStrict(locationService.position, prevPoint, nextPoint)).magnitude; if (dist < successDistanceKM) { if (si != stepIndex) Debug.Log(steps[si].string_instructions); stepIndex = si; pointIndex = pi; isFound = true; break; } } if (!isFound) pointIndex = 0; else break; } // If the user is not on the route, try to find another route. if (!isFound) { Debug.Log("Too far from the route. Try find a new route."); hasRoute = false; OnlineMapsGoogleDirections.Find(new OnlineMapsGoogleDirections.Params(locationService.position, toPlace) { key = googleAPIKey }).OnComplete += OnGoogleDirectionsComplete; } } } // For debugging purposes private void OnMapClick() { OnlineMapsLocationService.instance.emulatorPosition = OnlineMapsControlBase.instance.GetCoords(); } private void Start() { locationService = OnlineMapsLocationService.instance; // For debugging purposes OnlineMapsGoogleGeocoding.Find(new OnlineMapsGoogleGeocoding.GeocodingParams(fromPlace) { key = googleAPIKey }).OnComplete += delegate(string response) { Debug.Log(response); OnlineMapsGoogleGeocodingResult[] results = OnlineMapsGoogleGeocoding.GetResults(response); if (results != null && results.Length > 0) { OnlineMapsLocationService.instance.emulatorPosition = OnlineMaps.instance.position = results[0].geometry_location; } }; } }