using UnityEngine; public class SmoothMoveToGPSLocation : MonoBehaviour { public int targetZoom = 18; public float animationDuration = 5; // sec public AnimationCurve movementCurve = AnimationCurve.Linear(0, 0, 1, 1); public AnimationCurve zoomCurve = AnimationCurve.Linear(0, 0, 1, 1); private bool animationStarted = false; private Vector2 startLocation; private double startTileX; private double startTileY; private Vector2 endLocation; private double endTileX; private double endTileY; private int startZoom; private float progress; private OnlineMaps map; private Vector3 initialPosition; private void Start() { map = OnlineMaps.instance; OnlineMapsLocationService.instance.OnLocationInited += OnLocationInited; } private void OnLocationInited() { startZoom = map.zoom; startLocation = map.position; endLocation = OnlineMapsLocationService.instance.position; map.projection.CoordinatesToTile(startLocation.x, startLocation.y, 20, out startTileX, out startTileY); map.projection.CoordinatesToTile(endLocation.x, endLocation.y, 20, out endTileX, out endTileY); int mx = 1 << 20; if (Mathf.Abs((float) (endTileX - startTileY)) > mx / 2) { if (endTileX > startTileY) endTileY -= mx; else endTileY += mx; } initialPosition = map.transform.position; OnlineMapsControlBase.instance.allowUserControl = false; animationStarted = true; } private void Update() { if (!animationStarted) return; UpdateProgress(); UpdateZoom(); UpdatePosition(); } private void UpdatePosition() { float f = movementCurve.Evaluate(progress); double cx = Mathf.Lerp((float)startTileX, (float)endTileX, f); double cy = Mathf.Lerp((float)startTileY, (float)endTileY, f); int mx = 1 << 20; if (cx < 0) cx += mx; else if (cx > mx) cx -= mx; map.projection.TileToCoordinates(cx, cy, 20, out cx, out cy); map.SetPosition(cx, cy); } private void UpdateZoom() { float z = Mathf.Lerp(startZoom, targetZoom, zoomCurve.Evaluate(progress)); map.zoom = (int) z; float v = z - (int) z; float v1 = v + 1; map.transform.localScale = new Vector3(v1, v1, v1); Vector3 p = new Vector3(-v * map.tilesetSize.x / 2, 0, v * map.tilesetSize.y / 2); map.transform.localPosition = initialPosition - p; } private void UpdateProgress() { progress += Time.deltaTime / animationDuration; if (progress >= 1) { animationStarted = false; progress = 1; OnlineMapsControlBase.instance.allowUserControl = true; } } }