powerfun-unity/Assets/Scripts/UI/Prefab/Panel/BigMapController.cs

626 lines
19 KiB
C#

using Assets.Scripts.Apis;
using Mapbox.Unity.Map;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using Mapbox.Unity.MeshGeneration.Data;
using Newtonsoft.Json.Linq;
using Assets.Scripts;
using Mapbox.Utils;
using UnityEngine.UI;
using Assets.Scripts.Apis.Models;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using Mapbox.Examples;
using DG.Tweening;
using System.Globalization;
public class BigMapController : PFUIPanel
{
MapApi mapApi;
MapBoxApi mapboxApi;
AbstractMap mapManager;
//GameObject cube;
//GameObject cube1;
GameObject canvas,mainContainer;
GameObject content;
Text keyword;
UnityEngine.Object begin;
Sprite end;
private Dictionary<int, LineItem> linesCache = new Dictionary<int, LineItem>();
UnityEngine.Object tipsObject;
private MapItem _tips;
private MapItem tips
{
get
{
if (_tips == null)
{
#if !(UNITY_IOS || UNITY_ANDROID)
_tips = ((GameObject)Instantiate(tipsObject, canvas.transform.Find("TipsContainer"))).GetComponent<MapItem>();
#else
_tips = canvas.transform.Find("TipsContainer/MapItem-Mobile").GetComponent<MapItem>();
#endif
}
return _tips;
}
set
{
_tips = value;
}
}
int timer = 0;
private RawImage maskImage;
protected override void Awake()
{
//var rect = Camera.main.rect;
//rect.position = new Vector2(0, 200);
Camera.main.transform.position = new Vector3(0, 200);
Camera.main.transform.rotation = Quaternion.Euler(90, 0, 0);
//var cg = this.transform.Find("Canvas").GetComponent<CanvasGroup>();
//cg.alpha = 0;
mapApi = new MapApi();
mapboxApi = new MapBoxApi();
begin = Resources.Load("UI/Prefab/BigMap/Begin");
StartCoroutine("Main");
}
IEnumerator Main()
{
mapManager = this.transform.Find("Map").GetComponent<AbstractMap>();
//mapManager.MaxZoom = 4;
mapManager.OnInitialized += MapManager_OnInitialized;
mapManager.OnUpdated += MapManager_OnUpdated;
//// mapManager.OnTileFinished += MapManager_OnTileFinished;
//mapManager.SetZoom(5.8f);
//mapManager.SetCenterLatitudeLongitude(new Mapbox.Utils.Vector2d(32.051203, 118.771572));
this.transform.Find("Map").GetComponent<QuadTreeCameraMovement>()._referenceCamera = Camera.main;
canvas = this.transform.Find("Canvas").gameObject;
#if UNITY_ANDROID || UNITY_IOS
mainContainer = canvas.transform.Find("MainContainer").gameObject;
#else
mainContainer = canvas;
#endif
canvas.GetComponent<Canvas>().worldCamera = Camera.main;
var goList = mainContainer.transform.Find("SwitchMode");
#if UNITY_ANDROID || UNITY_IOS
SetRounded(goList, 52);
#else
SetRounded(goList, 64);
#endif
UIManager.AddEvent(goList.Find("GoList").gameObject, EventTriggerType.PointerClick, (e) =>
{
mapManager.Destroy();
UIManager.PopStack();
UIManager.ShowMapListPanel();
//this.gameObject.SetActive(false);
//DestroyImmediate(this.gameObject);
});
var panel = mainContainer.transform.Find("Panel");
#if UNITY_ANDROID || UNITY_IOS
base.SetRounded(panel, 20f);
#else
base.SetRounded(panel, 30f);
#endif
var qtcm = this.transform.Find("Map").GetComponent<QuadTreeCameraMovement>();
#if UNITY_ANDROID || UNITY_IOS
var scroll = panel.Find("Scroll View").gameObject;
UIManager.AddEvent(scroll, EventTriggerType.BeginDrag, (e) =>
{
qtcm.enabled = false;
});
UIManager.AddEvent(scroll, EventTriggerType.EndDrag, (e) =>
{
qtcm.enabled = true;
});
#else
UIManager.AddEvent(panel.gameObject, EventTriggerType.PointerEnter, (e) =>
{
qtcm.enabled = false;
});
UIManager.AddEvent(panel.gameObject, EventTriggerType.PointerExit, (e) =>
{
qtcm.enabled = true;
});
#endif
content = panel.Find("Scroll View").Find("Viewport").Find("Content").gameObject;
var input = panel.Find("InputField");
base.SetRounded(input, 20f);
input.GetComponent<InputField>().onEndEdit.AddListener((text) =>
{
if (Input.GetKeyDown(KeyCode.Return))
{
this.Search(null);
}
});
keyword = input.Find("Text").GetComponent<Text>();
var searchBtn = input.Find("Search").gameObject;
UIManager.AddEvent(searchBtn, EventTriggerType.PointerClick, Search);
#if UNITY_ANDROID || UNITY_IOS
tipsObject = Resources.Load("UI/Prefab/MapList/MapItem-Mobile");
#else
tipsObject = Resources.Load("UI/Prefab/MapList/MapItem");
#endif
//tips = ((GameObject)Instantiate(tipsObject, canvas.transform.Find("TipsContainer"))).GetComponent<Tips>();
//tips.Hide();
BindHeadImage();
maskImage = canvas.transform.Find("MaskImage").GetComponent<RawImage>();
maskImage.DOFade(0, 0.8f);
yield return null;
}
/// <summary>
/// 绑定头像
/// </summary>
void BindHeadImage()
{
var headImage = mainContainer.transform.Find("HeadImage").GetComponent<RawImage>();
//var material = Instantiate(Resources.Load<Material>("UI/Material/RoundedCornersTextureMaterial"));
var rect = ((RectTransform)headImage.transform).rect;
//material.SetVector(Shader.PropertyToID("_WidthHeightRadius"), new Vector4(rect.width, rect.height, rect.height, 0));
//headImage.material = material;
SetRounded(headImage.transform, rect.height);
Utils.DisplayHead(headImage, App.CurrentUser.WxHeadImg);
UIManager.AddEvent(headImage.gameObject, EventTriggerType.PointerClick, (e) =>
{
UIManager.ShowUserInfoPanel();
});
}
// Start is called before the first frame update
protected override void Start()
{
//var mapObject = this.transform.Find("Map");
}
private async void Search(BaseEventData e)
{
if (string.IsNullOrWhiteSpace(keyword.text))
{
//yield return null;
return;
}
Debug.Log(keyword.text);
//UIManager.ShowLoadingDialogBox();
//Utils.showLoading(this.gameObject);
UIManager.ShowLoadingDialogBox();
var infoStr = await mapboxApi.GetAddressInfo(keyword.text);
//Debug.Log(infoStr);
var info = Newtonsoft.Json.Linq.JObject.Parse(infoStr);
var features = (info["features"] as JArray);
if (features.Count > 0) {
var center = features.First()["center"];
mapManager.UpdateMap(new Vector2d(Convert.ToDouble(center[1]), Convert.ToDouble(center[0])));
}
UIManager.HideLoadingDialogBox();
}
private void MapManager_OnInitialized()
{
mapManager.UpdateMap(5.8f);
Load();
}
private void MapManager_OnUpdated()
{
//Debug.Log("update "+ mapManager.Zoom);
if(mapManager.Zoom <= 4.8)
{
mapManager.OnUpdated -= MapManager_OnUpdated;
maskImage.gameObject.SetActive(true);
maskImage.DOFade(1f, 0.9f).SetEase(Ease.InSine).OnComplete(() =>
{
this.Close();
UIManager.PopStack();
UIManager.ShowEarthPanel(mapManager.CenterLatitudeLongitude.x, mapManager.CenterLatitudeLongitude.y);
});
return;
}
foreach (var item in linesCache)
{
//if(item.Value.LineObject != null)
//{
// item.Value.LineObject.Destroy();
// item.Value.LineObject = null;
//}
//if(item.Value.BeginMarker != null)
//{
// item.Value.BeginMarker.Destroy();
// item.Value.BeginMarker = null;
//}
CreateLine(item.Key, item.Value);
}
timer += 1;
Invoke("Load", 0.3f);
//Load();
}
async void Load()
{
if (timer >1)
{
timer--;
return;
}
timer = 0;
var s1 = Camera.main.ScreenToWorldPoint(new Vector3(340f, 0f, 180f));
//Debug.Log(s1);
var start = mapManager.WorldToGeoPosition(s1);
//Debug.Log(start);
var worldPoint = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 180f));
var end = mapManager.WorldToGeoPosition(worldPoint);
//cube.transform.position = worldPoint;
//cube1.transform.position = s1;
//Debug.Log(end);
//Screen.width
//map.WorldToGeoPosition(start)
var bounds = $"{ start.y.ToString(CultureInfo.InvariantCulture) },{ start.x.ToString(CultureInfo.InvariantCulture) };{ end.y.ToString(CultureInfo.InvariantCulture) },{ end.x.ToString(CultureInfo.InvariantCulture) }";
var res = await mapApi.GetNearRouteAsync((float)mapManager.CenterLatitudeLongitude.x, (float)mapManager.CenterLatitudeLongitude.y,
mapManager.Zoom, bounds);
if(res.result == false)
{
Debug.LogError(res.errMsg);
return;
}
//Debug.Log("条数:"+res.data.Count);
var lines = await mapApi.GetDetailsAsync(res.data.Select(d => d.Id).ToArray());
var aa = Newtonsoft.Json.Linq.JObject.Parse(lines);
//var points = (aa["data"] as JArray).First()["Points"] as JArray;
var ids = new List<int>();
foreach (var line in (aa["data"] as JArray))
{
var id = line.Value<int>("Id");
ids.Add(id);
var points = line["Points"] as JArray;
if (linesCache.ContainsKey(id))
{
continue;
}
var pp1 = new List<Vector2d>();
foreach (var item in points)
{
pp1.Add(new Mapbox.Utils.Vector2d(item[0].ToObject<double>(), item[1].ToObject<double>()));
}
if (!linesCache.ContainsKey(id))
{
linesCache.Add(id, new LineItem { Points = pp1, Model = res.data.Single(d=>d.Id == id) });
}
CreateLine(id, linesCache[id]);
//Load();
}
foreach (var item in linesCache.ToList())
{
if(ids.All(id=>id != item.Key))
{
item.Value.Destroy();
linesCache.Remove(item.Key);
if(item.Value.Selected)
{
tips.Hide();
#if !(UNITY_ANDROID || UNITY_IOS)
tips = null;
#endif
}
}
}
}
//GameObject direct;
void CreateLine(int id, LineItem line)
{
#region 线
List<Vector2d> pp1 = line.Points;
var dat = new List<Vector3>();
foreach (var item in pp1)
{
var pp = mapManager.GeoToWorldPosition(item);
pp.y += 0.3f;
dat.Add(pp);
}
var feat = new VectorFeatureUnity();
feat.Points.Add(dat);
var direct = line.LineObject;
LineRenderer lineRender;
if (direct == null)
{
direct = new GameObject($"MapRoute-{ id }");
direct.transform.SetParent(this.transform);
lineRender = direct.AddComponent<LineRenderer>();
lineRender.material = new Material(Shader.Find("Sprites/Default"));
line.LineObject = direct;
lineRender.startColor = lineRender.endColor = Color.white; //Utils.HexToColor("F93086");
//设置宽度
lineRender.startWidth = 1.2f;
lineRender.endWidth = 1.2f;
lineRender.numCornerVertices = 90;
}
else
{
lineRender = direct.GetComponent<LineRenderer>();
}
//lineRender.SetWidth(0.5f, 0.5f);
lineRender.positionCount = dat.Count;
//lineRender.SetVertexCount(dat.Count);
lineRender.SetPositions(feat.Points[0].ToArray());
#endregion
#region
if (linesCache[id].Item == null)
{
#if UNITY_ANDROID || UNITY_IOS
var itemObject = Resources.Load("UI/Prefab/BigMap/Mobile/Item");
#else
var itemObject = Resources.Load("UI/Prefab/BigMap/Item");
#endif
var itemObject1 = (GameObject)Instantiate(itemObject, content.transform, false);
var iii = itemObject1.GetComponent<Item>();
iii.SetModel(line.Model);
line.Item = iii;
iii.onClick = () =>
{
if(_tips != null)
{
_tips.Hide();
#if !(UNITY_ANDROID || UNITY_IOS)
_tips = null;
#endif
}
if (line.Selected)
{
line.Selected = false;
//tips.Hide();
#if !(UNITY_ANDROID || UNITY_IOS)
tips = null;
#endif
return;
}
line.Selected = true;
//iii.Selected(true);
var position = line.BeginMarker.transform.position;
//position.z += 25;
tips.Show(position, line.Model);
foreach (var item in linesCache)
{
if(item.Key != line.Model.Id)
{
item.Value.Selected = false;
//item.Value.Item.Selected(false);
}
}
};
}
#endregion
#region marker
if (line.BeginMarker == null)
{
var beginInstance = (GameObject)Instantiate(begin, canvas.transform.Find("MarkerContainer").transform);
line.BeginMarker = beginInstance;
UIManager.AddEvent(line.BeginMarker, EventTriggerType.PointerClick, new UnityAction<BaseEventData>((e) =>
{
if (line.Selected)
{
line.Selected = false;
tips.Hide();
return;
}
line.Selected = true;
var position = line.BeginMarker.transform.position;
//position.z += 25;
tips.Show(position, line.Model);
foreach (var item in linesCache)
{
if (item.Key != line.Model.Id)
{
item.Value.Selected = false;
//item.Value.Item.Selected(false);
}
}
}));
}
line.BeginMarker.transform.localScale = new Vector3(2,2);
//beginInstance.transform.localRotation = new Quaternion(90,0,0,0);
line.BeginMarker.transform.position = ConverToPosition(line.Points.First());
#endregion
if (line.Selected)
{
line.Selected = true;
var position = line.BeginMarker.transform.position;
//position.z += 25;
//tips.Show(position, line.Model);
tips.Move(position);
}
}
/// <summary>
/// 转换地理坐标到屏幕坐标
/// </summary>
/// <param name="vector"></param>
/// <returns></returns>
Vector3 ConverToPosition(Vector2d vector)
{
var worldPosition = mapManager.GeoToWorldPosition(vector);//32.061255, 118.80925
var vp = Camera.main.WorldToViewportPoint(worldPosition);
vp.z = 180f;
////Debug.Log(vp);
//var wd = Camera.main.WorldToScreenPoint(worldPosition);
var wd = Camera.main.ViewportToWorldPoint(vp);
return wd;
}
// Update is called once per frame
void Update()
{
//Debug.Log(Input.mousePosition.x + "," + Input.mousePosition.y + "," + Input.mousePosition.z);
//timer += Time.deltaTime;
// Check if there is a touch
#if UNITY_IOS || UNITY_ANDROID
if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)) //检测手值的触碰
{
// Check if finger is over a UI element
if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) //监视是否触碰UI
{
var line = linesCache.Select(d => d.Value).FirstOrDefault(l => l.Selected);
if (line != null)
{
line.Selected = false;
if (_tips != null)
{
_tips.Hide();
}
}
}
}
#else
//鼠标点击空白处,清除选择的路线
if (Input.GetMouseButtonDown(0) && EventSystem.current.IsPointerOverGameObject() == false)
{
var line = linesCache.Select(d=>d.Value).FirstOrDefault(l => l.Selected);
if(line != null)
{
line.Selected = false;
if (_tips != null)
{
_tips.Hide();
_tips = null;
}
}
}
#endif
}
public void Show(double lat, double lon)
{
//var cg = this.transform.Find("Canvas").GetComponent<CanvasGroup>();
//cg.alpha = 0;
var color = maskImage.color;
color.a = 1;
maskImage.color = color;
base.Show();
if(lat != 0 && lon != 0)
{
mapManager.SetCenterLatitudeLongitude(new Vector2d(lat, lon));
}
maskImage.DOFade(1f, 0.5f).OnComplete(()=> {
maskImage.gameObject.SetActive(false);
});
//cg.DOFade(1f, 0.3f);
}
public override void Close()
{
//base.Close();
DestroyImmediate(this.gameObject);
}
class LineItem
{
public List<Vector2d> Points { get; set; }
public GameObject LineObject { get; set; }
public GameObject BeginMarker { get; set; }
public NearRouteModel Model { get; set; }
public Item Item { get; set; }
private bool _Selected = false;
public bool Selected {
get
{
return _Selected;
}
set
{
_Selected = value;
Item.Selected(value);
var lineRender = LineObject.GetComponent<LineRenderer>();
if (value)
{
lineRender.startColor = lineRender.endColor = Utils.HexToColor("F93086");
}
else
{
lineRender.startColor = lineRender.endColor = Color.white;
}
}
}
public void Destroy()
{
//Debug.Log($"销毁{ item.Key }, { item.Value.Item != null }");
LineObject.Destroy();
BeginMarker.Destroy();
if (Item != null)
{
Item.gameObject.Destroy();
}
}
}
}