// Utilized Libraries
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System;
using System.Collections;
// Map
// This class represents an interactive map that updates every 5 seconds by taking the location from the server via phone app.
public class Map : MonoBehaviour
{
// Questo è la API di Google per l'utilizzo della API google STATIC Map API.
private string apiKey = "MY API";
public enum resolution { low = 1, high = 2 }; // MAP RESOLUTION
public resolution mapResolution = resolution.high; // HIGH RES.
public enum type { roadmap, satellite, gybrid, terrain }; // TYPES OF MAP OF GOOGLE STATIC MAP API
private type mapType = type.satellite; // INITIAL MAP TYPE
private int mapWidth = 800;
private int mapHeight = 540;
// Definition of latitude and longitude variables.
private float lat = 0;
private float lon = 0;
private int zoom = 18;
//DEFINITION OF URL
private string url = "";
private Rect rect;
// START
void Start()
{
StartCoroutine(UpdateMap());
}
IEnumerator UpdateMap()
{
while (true)
{
string latLast = "";
string lonLast = "";
//Request from the server to take the coordinates.
using (UnityWebRequest webRequest = UnityWebRequest.Get("MY SERVER"))
{
// SEND REQUEST
yield return webRequest.SendWebRequest();
if (webRequest.result != UnityWebRequest.Result.Success)
{ //Errore.
Debug.LogError("Error: " + webRequest.error);
}
else
{
// GET CORDINATES
Coordinates data = JsonUtility.FromJson<Coordinates>(webRequest.downloadHandler.text);
// Debug.Log("Coordinate: " + data.coordinates);
//EXTRACT LAT AND LON.
String[] parts = data.coordinates.Split(',');
latLast = parts[0];
lonLast = parts[1];
//Taking map measurements on Unity
//rect = gameObject.GetComponent<RawImage>().rectTransform.rect;
//mapWidth = (int)Math.Round(rect.width);
//mapHeight = (int)Math.Round(rect.height);
//Query
Debug.Log(mapType);
url = "https://maps.googleapis.com/maps/api/staticmap?" +
"center=" + latLast + "," + lonLast +
"&zoom=" + zoom +
"&markers=color:red|" + latLast + "," + lonLast +
"&size=" + mapWidth + "x" + mapHeight +
"&scale=" + (int)resolution.high +
"&maptype=" + mapType +
"&key=" + apiKey;
// Get RAW IMAGE Unity.
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{//Errore
Debug.Log("WWW ERROR: " + www.error);
}
else
{
gameObject.GetComponent<RawImage>().texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
}
}
}
yield return new WaitForSeconds(2); // WAIT OF 5 SEC
}
}
[Serializable]
private class Coordinates
{
public string coordinates;
}
public void setMapTypeRoadMap()
{
StopAllCoroutines();
mapType = type.roadmap;
}
}
setMapTypeRoadMap is not called from within this script.
The problem statement „can‘t stop“ is unclear, please provide more details.
As above, please don’t use the thread title as a full explanation of a problem, it should be nothing more than a synopsis.
Please provide some detail as to what you’re expecting to happen compared to what is happening. Also include some detail on what you’ve done to verify/debug the problem yourself.
Simply posting a bunch of code for others to debug isn’t useful in many cases.
Thanks.
Okay, so i call setMapTypeRoadMap() on a button on unity, this method setMapTypeRoadMap() should set my mapType to type.roadmap but after i call the method, it looks like it doesn’t change anything, because it looks like the initial coroutine doesn’t stop with StopAllCoroutines().
I tried many things, using flags, using threads instead of Coroutines but nothing works, i’ve also tried to assing the coroutine to a Variable and calling inside a Coroutine, but nothing. Also i tried some Debug.Log() to check if the method setMapTypeRoadMap() is actually called, and it works.
So the thing is, the Coroutine inside the loop while(true) doesn’t stop even after a StopCoroutine() or StopAllCoroutines().
Okay, so i call setMapTypeRoadMap() on a button on unity, this method setMapTypeRoadMap() should set my mapType to type.roadmap but after i call the method, it looks like it doesn’t change anything, because it looks like the initial coroutine doesn’t stop with StopAllCoroutines().
I tried many things, using flags, using threads instead of Coroutines but nothing works, i’ve also tried to assing the coroutine to a Variable and calling inside a Coroutine, but nothing. Also i tried some Debug.Log() to check if the method setMapTypeRoadMap() is actually called, and it works.
So the thing is, the Coroutine inside the loop while(true) doesn’t stop even after a StopCoroutine() or StopAllCoroutines().
May sound like a silly question but are you sure there’s only one instance of this script active? Happens more often that you’d imagine.
Yes! I’m 100% sure there’s only one instance of this script, i’ve seen multiple people facing issues with StopAllCoroutines(), even tho i tried their way to fix like they did, but it didnt work
It’s worth noting that StopAllCoroutines()
stops all coroutines that have been started on that particular game object you’re calling it on. It does not stop every single coroutine that may be executing; it is not a static method. You need to call it on a component of the same game object that started the coroutine.
Can you tell me how to fix it in the code, i did understand what you just told me but i dont know how to implement it, thank you so much in advance!
But that’s likely confirmation bias because you already said that explicitly using “StopCoroutine” doesn’t work in your case either so they problem is due to something they were doing (differently).
No, we can not because many details are up to your project that we don’t have.
For the future: 100% certainty does not exist, ever I would even bet that you may have this script two times, once in the scene and maybe once on a prefab? You may have linked the prefab and not the actual instance in the scene. This is also a common issue / mistake. Prefabs are actual objects as well, though they don’t live in the scene but in the project. You can actually call methods on those objects but the prefab is something different from an instance / clone of a prefab.
The easiest solution to debug your issue is adding a Debug.Log statement like this:
public void setMapTypeRoadMap()
{
Debug.Log("setMapTypeRoadMap called", gameObject);
StopAllCoroutines();
mapType = type.roadmap;
}
Note the second argument to the Log method. It’s a context object and can be any UnityEngine.Object derived type. When you provide a context object, the Unity editor will highlight THAT object when you click on the log message in the console. So add this log statement, play your game, press your button to call that method, pause the editor and click on the log message and observe which object gets “pinged”. If it’s not the object in the scene, you call the method on the wrong object.