using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Minimap : MonoBehaviour
{
public int zoom = 10;
public RectTransform tileContainer;
private static OnlineMaps map;
private Dictionary<ulong, TileItem> tiles;
private List<ulong> keysForRemove;
private void OnTileDownloaded(OnlineMapsTile tile)
{
if (tiles.ContainsKey(tile.key))
{
TileItem item = tiles[tile.key];
if (string.IsNullOrEmpty(tile.www.error))
{
Texture2D texture = new Texture2D(128, 128);
tile.www.LoadImageIntoTexture(texture);
texture.wrapMode = TextureWrapMode.Clamp;
item.SetTexture(texture);
UpdateMinimap();
}
}
}
private void Start()
{
map = OnlineMaps.instance;
zoom = map.zoom - 5;
map.OnChangePosition += UpdateMinimap;
map.OnChangeZoom += delegate { zoom = map.zoom - 5; UpdateMinimap(); };
OnlineMapsTile.OnTileDownloaded += OnTileDownloaded;
tiles = new Dictionary<ulong, TileItem>();
UpdateMinimap();
}
private void UpdateMinimap()
{
//gameObject.transform.rotation = new Quaternion(0, 0, 0, 0);
int maxX = 1 << zoom;
double lng, lat;
double lng2, lat2;
map.GetPosition(out lng, out lat);
map.GetBottomRightPosition(out lng2, out lat2);
lng = (lng2 + lng *2) /3;
lat = (lat2 + lat *2) /3;
double tx, ty;
map.projection.CoordinatesToTile(lng, lat, zoom, out tx, out ty);
int itx = (int) tx - 1;
int ity = (int) ty - 1;
if (itx < 0) itx -= maxX;
if (ity < 0) ity = 0;
foreach (KeyValuePair<ulong, TileItem> pair in tiles)
{
pair.Value.used = false;
}
for (int x = 0; x < 3; x++)
{
int cx = x + itx;
for (int y = 0; y < 3; y++)
{
int cy = y + ity;
ulong tileKey = OnlineMapsTile.GetTileKey(zoom, cx, cy);
TileItem tile;
if (tiles.ContainsKey(tileKey)) tile = tiles[tileKey];
else
{
tile = new TileItem(cx, cy, zoom, tileContainer);
tiles.Add(tile.key, tile);
}
tile.used = true;
tile.UpdatePosition(tx, ty);
}
}
UnloadUnusedTiles();
}
private void UnloadUnusedTiles()
{
if (keysForRemove == null) keysForRemove = new List<ulong>(9);
else keysForRemove.Clear();
foreach (KeyValuePair<ulong, TileItem> pair in tiles)
{
if (!pair.Value.used)
{
keysForRemove.Add(pair.Value.key);
pair.Value.Dispose();
}
}
if (keysForRemove.Count > 0)
{
foreach (ulong key in keysForRemove)
{
tiles.Remove(key);
}
}
}
internal class TileItem
{
public OnlineMapsTile tile;
public ulong key;
public GameObject instance;
public bool used;
private int tx;
private int ty;
private RectTransform rectTransform;
private RawImage rawImage;
public TileItem(int tx, int ty, int zoom, RectTransform container)
{
this.tx = tx;
this.ty = ty;
tile = new OnlineMapsTile(tx, ty, zoom, map, false);
key = tile.key;
map.StartDownloadTile(tile);
instance = new GameObject(zoom + "x" + tx + "+" + ty);
rawImage = instance.AddComponent<RawImage>();
rectTransform = instance.transform as RectTransform;
rectTransform.SetParent(container);
rectTransform.anchorMin = new Vector2(0, 1);
rectTransform.anchorMax = new Vector2(0, 1);
rectTransform.pivot = new Vector2(0, 1);
rectTransform.sizeDelta = new Vector2(OnlineMapsUtils.tileSize, OnlineMapsUtils.tileSize);
}
public void Dispose()
{
tile.Dispose();
Destroy(instance);
tile = null;
instance = null;
rectTransform = null;
}
internal void UpdatePosition(double cx, double cy)
{
double px = (tx - cx) * (OnlineMapsUtils.tileSize);
double py = (cy - ty) * (OnlineMapsUtils.tileSize);
rectTransform.localPosition = new Vector3((float)px, (float)py, 0);
}
public void SetTexture(Texture2D texture)
{
rawImage.texture = texture;
}
}
}
I added a bit to start so the minimap also zooms out when the player zooms out.