using Mapbox.Unity.Map; using Mapbox.Unity.MeshGeneration.Data; using Mapbox.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UI; namespace Assets.Scenes.Ride.Scripts { public class InitMiniMapProvider : MonoBehaviour { [SerializeField] AbstractMap _map; [SerializeField] Camera _minicamera; [SerializeField] GameObject _player; CyclingController cyclingCotroller; public PlayerController playerController; GameObject _mipMapRoute; public RectTransform RectRoot;//rawImage void Start() { cyclingCotroller = FindObjectOfType(); //playerController = FindObjectOfType(); if (cyclingCotroller != null) { var mapdata = cyclingCotroller.GetMapData(); //初始化map //var point = cyclingCotroller.GetCenterCoordinate(); if (_map != null && mapdata !=null) { _map.OnInitialized += _map_OnInitialized; _map.OnUpdated += _map_OnUpdated; _map.Initialize(new Vector2d(mapdata.Center[0], mapdata.Center[1]), 12); var bbox = mapdata.Bbox; var targetbounds = new Vector2dBounds(new Vector2d(bbox[1], bbox[0]), new Vector2d(bbox[3], bbox[2])); var screenBounds = GetScreenBounds(); var z = SetZoomToFitBounds(targetbounds, screenBounds); } RectRoot = transform.parent.Find("SingleUI/Panel/MiniMap/MiniMap").GetComponent(); } } float timer = 0; private void Update() { if (playerController != null) { var tr = transform.parent.Find("SingleUI/Panel/MiniMap/MiniMap/arrow"); tr.SetSiblingIndex(9999); _player.transform.localPosition = _map.GeoToWorldPosition(playerController.Currentlatlong); Vector2 vp2 = _minicamera.WorldToViewportPoint(_player.transform.localPosition);//将三维物体的世界坐标转换为视口坐标 ((RectTransform)tr.transform).anchoredPosition = new Vector2((vp2.x * RectRoot.sizeDelta.x) - (RectRoot.sizeDelta.x * 0.5f), (vp2.y * RectRoot.sizeDelta.y) - (RectRoot.sizeDelta.y * 0.5f)); } timer += Time.deltaTime; while (timer>=1) { CreateMiniPath(); timer = 0; } } void CreateMiniPath() { if (playerController == null) return; var dat = new List(); var mapData = cyclingCotroller.GetMapData(); if (mapData != null) { var count = mapData.List.Count; var interval = Math.Max(Math.Ceiling(count / 100D), 1f); for (int i = 0; i < mapData.List.Count; i++) { if (i % interval == 0) { var point = mapData.List[i].Point; Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0], point[1])); item.y += 5f; if (playerController.CurrentIndex >= i-1) { dat.Add(item); } } } var feat = new VectorFeatureUnity(); feat.Points.Add(dat); CreateRedLineRender(feat);//创建小地图路线 } } private bool init = false; private void _map_OnInitialized() { init = true; var visualizer = _map.MapVisualizer; visualizer.OnMapVisualizerStateChanged += (s) => { if (s == ModuleState.Finished) { } }; } #region Camera 自适应 /// /// https://github.com/mapbox/mapbox-unity-sdk/issues/1580 /// /// 路线的边界 /// 小地图边界 private int SetZoomToFitBounds(Vector2dBounds targetBounds, Vector2dBounds screenBounds) { var targetLonDelta = targetBounds.East - targetBounds.West; var targetLatDelta = targetBounds.North - targetBounds.South; var screenLonDelta = screenBounds.East - screenBounds.West; var screenLatDelta = screenBounds.North - screenBounds.South; var zoomLatMultiplier = screenLatDelta / targetLatDelta; var zoomLonMultiplier = screenLonDelta / targetLonDelta; var latZoom = Math.Log(zoomLatMultiplier, 2); var lonZoom = Math.Log(zoomLonMultiplier, 2); var zoom = (float)(_map.Zoom + Math.Min(latZoom, lonZoom)); _map.SetZoom((float)Math.Floor(zoom)); _map.UpdateMap(); return (int)Math.Floor(zoom); } private Vector2dBounds GetScreenBounds() { var screenWidth = UnityEngine.Screen.width; var screenHeight = UnityEngine.Screen.height; var sw_world = _minicamera.ViewportToWorldPoint(new Vector3(0.25f, 0.1f, 160)); var sw = _map.WorldToGeoPosition(sw_world); var ne_world = _minicamera.ViewportToWorldPoint(new Vector3(0.75f, 0.9f, 90)); var ne = _map.WorldToGeoPosition(ne_world); return new Vector2dBounds(new Vector2d(sw.x, sw.y), new Vector2d(ne.x, ne.y)); } #endregion #region 创建小地图路线 private void _map_OnUpdated() { CreateMiniRoute(); } void CreateMiniRoute() { var meshData = new MeshData(); var dat = new List(); var mapData = cyclingCotroller.GetMapData(); if (mapData != null) { var count = mapData.List.Count; var interval = Math.Max(Math.Ceiling(count / 100D),1f); for (int i = 0; i < mapData.List.Count; i++) { if(i% interval == 0) { var point = mapData.List[i].Point; Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0], point[1])); item.y += 1f; dat.Add(item); } } var feat = new VectorFeatureUnity(); feat.Points.Add(dat); CreateLineRender(feat);//创建小地图路线 } } //创建小地图路线 void CreateLineRender(VectorFeatureUnity feat) { if (_mipMapRoute != null) { _mipMapRoute.Destroy(); } _mipMapRoute = new GameObject("MiniMapRoute"); _mipMapRoute.transform.parent = transform; var lineRender = _mipMapRoute.AddComponent(); lineRender.material = Instantiate(Resources.Load("UI/Material/1")); var dat = feat.Points[0]; lineRender.endColor = Color.white; lineRender.startColor = Color.white; //设置宽度 lineRender.startWidth = 10f; lineRender.endWidth = 10f; lineRender.positionCount = dat.Count; lineRender.SetPositions(feat.Points[0].ToArray()); lineRender.numCornerVertices = 20; lineRender.numCapVertices = 20; lineRender.loop = false; _mipMapRoute.layer = 9; } GameObject _mipMapPath; void CreateRedLineRender(VectorFeatureUnity feat) { if (_mipMapPath != null) { _mipMapPath.Destroy(); } _mipMapPath = new GameObject("MiniMapPath"); _mipMapPath.transform.parent = transform; var lineRender = _mipMapPath.AddComponent(); lineRender.material = Instantiate(Resources.Load("UI/Material/2")); var dat = feat.Points[0]; lineRender.endColor = Color.red; lineRender.startColor = Color.red; //设置宽度 lineRender.startWidth = 10f; lineRender.endWidth = 10f; lineRender.positionCount = dat.Count; lineRender.SetPositions(feat.Points[0].ToArray()); lineRender.numCornerVertices = 20; lineRender.numCapVertices = 20; lineRender.loop = false; _mipMapPath.layer = 9; } #endregion } }