using HxGame; using HxGame.Data; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Xml; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Networking; using UnityEngine.UI; public partial class MapManager : MonoBehaviour { //地图宽高缩放 public const int CELLSCALE = 100; public delegate void LoadFinishedCallback(); public LoadFinishedCallback onLoadFinishedCallback; //public delegate void CloseMapCallback(); //public CloseMapCallback onCloseMapCallback; private static MapManager _mapManager = null; public static MapManager Instance { get { if (_mapManager == null) _mapManager = FindObjectOfType(); return _mapManager; } } [HideInInspector] public int mapWidth = 0; [HideInInspector] public int mapHeight = 0; private int _maxWidth; //记录最大宽度索引 private int _maxHeight; //记录最大高度索引 private int _cellWidth; private int _cellHeight; private int _cellRows; private int _cellCols; //public CellNode[,] cellNodes; private int _curOpenMapId; private Material _cellMoveMat; private Material _cellObsMat; private Material _cellHideMat; private Material _cellDefaultMat; private Material _cellReturnMat; //回城点 private Material _cellReliveMat; //复活点 private Material _cellTeleportMat; //传送点 private Material _cellNpcMat; //npc位置 private Material _cellPathNodeMat; //pathNode private Material _cellTriggerMat; //trigger private bool _StartEditor; private float _brushRadius; private CellType _brushCellType; public int CellRows { get { return _cellRows; } } public int CellCols { get { return _cellCols; } } public int CellWidth { get { return _cellWidth; } } public int CellHeight { get { return _cellHeight; } } public int MaxWidth { get { return _maxWidth; } } public int MaxHeight { get { return _maxHeight; } } private UnityEngine.Object _cellAsset = null; private GameObject _curPathObj = null; private void Start() { _cellAsset = Resources.Load("Prefabs/Cell"); if (_cellAsset == null) { UIWindow.Instance.ShowMessage("加载cell.prefab失败"); return; } foreach (CellLayer layer in Enum.GetValues(typeof(CellLayer))) { List gos = new List(); _layCellsMap.Add(layer, gos); } _cellMoveMat = Resources.Load("Materials/cellMoveMat"); _cellObsMat = Resources.Load("Materials/cellObsMat"); _cellHideMat = Resources.Load("Materials/cellHideMat"); _cellDefaultMat = Resources.Load("Materials/cellDefaultMat"); _cellReturnMat = Resources.Load("Materials/cellReturnMat"); _cellReliveMat = Resources.Load("Materials/cellReliveMat"); _cellTriggerMat = Resources.Load("Materials/cellTriggerMat"); _cellTeleportMat = Resources.Load("Materials/cellTeleportMat"); _cellNpcMat = Resources.Load("Materials/cellNpcMat"); _cellPathNodeMat = Resources.Load("Materials/cellPathNodeMat"); UIWindow.Instance.uiCreateMap.onCreatedMapCallback += OnCreatedMap; Cleanup(); } private void OnCreatedMap(int mapId, int mapWidth, int mapHeight) { this.mapWidth = mapWidth; this.mapHeight = mapHeight; _curOpenMapId = mapId; } public void StartEditor() { if (_curOpenMapId < 0) { UIWindow.Instance.ShowMessage("请先打开地图"); return; } _StartEditor = true; _curEditCellType = EditCellType.None; } public void CloseEditor() { _StartEditor = false; } public void SetBrush(float radius, CellType type) { _brushRadius = radius; _brushCellType = type; } public void SaveCellsXml() { if(cellsNode.Length == 0) { UIWindow.Instance.ShowMessage("网格数据还没生成"); return; } string path = PathUtil.GetXmlPath(_curOpenMapId, "Obs"); if (File.Exists(path)) File.Delete(path); XmlDocument xml = new XmlDocument(); XmlDeclaration node = xml.CreateXmlDeclaration("1.0", "utf-8", "no"); xml.AppendChild(node); XmlElement Root = xml.CreateElement("Item"); xml.AppendChild(Root); Root.SetAttribute("ID", _curOpenMapId.ToString()); Root.SetAttribute("MapWidth", mapWidth.ToString()); Root.SetAttribute("MapHeight", mapHeight.ToString()); Root.SetAttribute("CellWidth", _cellWidth.ToString()); Root.SetAttribute("CellHeight", _cellHeight.ToString()); CellNode cell = null; StringBuilder sb = new StringBuilder(); //tempSafeAreasConfig.Clear(); for (int row = 0; row < _cellRows; row++) { for (int col = 0; col < _cellCols; col++) { cell = GetCell(col, row); if(cell == null) { UIWindow.Instance.ShowMessage("读取网格错误"); return; } //如果是安全区格子,加上安全区枚举位运算类型 //if (CheckIsSafeCell(cell)) //{ // cell.cellType |= CellType.Safe; //} sb.Append(string.Format($"{row},{col},{(int)cell.cellType};")); } } sb.Remove(sb.Length - 1, 1); string Value = sb.ToString(); Root.SetAttribute("Value", Value); xml.Save(path); UIWindow.Instance.ShowMessage("保存地图网格xml成功."); } List tempSafeAreasConfig = new List(); public void CloseMap() { if (_curOpenMapId <= 0) return; RemoveAllCells(); UIWindow.Instance.uiCellInfo.CloseMap(); UIWindow.Instance.uiCreateMap.CloseMap(); UIWindow.Instance.uiMonstersPanel.RemoveAll(); Cleanup(); } private void Cleanup() { mapWidth = 0; mapHeight = 0; _maxWidth = 0; _maxHeight = 0; _cellWidth = -1; _cellHeight = -1; _cellRows = -1; _cellCols = -1; _curOpenMapId = -1; _StartEditor = false; _brushRadius = 0; _brushCellType = CellType.None; cellsNode = null; } private void Update() { bool bHoverUI = EventSystem.current != null && EventSystem.current.IsPointerOverGameObject(); if (bHoverUI) return; UpdateCamera(); if (_curEditCellType != EditCellType.None) { EditSpecialMapPoint(_curEditCellType); return; } if (!_StartEditor) return; if (Input.GetMouseButton(0)) { EditCell(); } } private void EditCell() { //从摄像机发出到点击坐标的射线 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { GameObject gameObj = hitInfo.collider.gameObject; if (gameObj.layer != LayerMask.NameToLayer("MapCell")) return; if (_brushRadius == 0) { CellType ct = SetCellType(gameObj.name, _brushCellType); ShowCellType(gameObj, ct); return; } Collider[] hits = Physics.OverlapSphere(gameObj.transform.position, _brushRadius);// LayerMask.NameToLayer("MapCell") if (hits.Length > 0) { for (int i = 0; i < hits.Length; i++) { CellType ct = SetCellType(hits[i].name, _brushCellType); ShowCellType(hits[i].gameObject, ct); } } } } private void EditSpecialMapPoint(EditCellType type) { if (Input.GetMouseButtonUp(0)) { if(type == EditCellType.NpcPath) { if (_curPathObj == null) return; UIWindow.Instance.uiNpcsPanel.curActiveList.Add(_curPathObj.name); UIWindow.Instance.uiNpcsPanel.curActiveInput.text += $"[{_curPathObj.name.Replace('_', ',')}]"; AddNpcPathSize(); _curPathObj = null; } else if (type == EditCellType.MonsterPath) { if (_curPathObj == null) return; //UIWindow.Instance.uiMonstersPanel_old.curActiveList.Add(_curPathObj.name); //UIWindow.Instance.uiMonstersPanel_old.curActiveInput.text += $"[{_curPathObj.name.Replace('_', ',')}]"; AddMonsterPathSize(); _curPathObj = null; } else { _curEditCellType = EditCellType.None; return; } } if(type == EditCellType.NpcPath) { if(Input.GetKeyDown(KeyCode.Escape)) { string last = $"NpcPath{_curNpcPointIdx}{GetCurNpcPathIdx()}"; GameObject lastObj = GameObject.Find(last); DestroyImmediate(lastObj); _curEditCellType = EditCellType.None; return; } } else if (type == EditCellType.MonsterPath) { if (Input.GetKeyDown(KeyCode.Escape)) { string last = $"MonsterPath{_curMonsterPoint.areaIdx}{GetCurMonsterPathIdx()}"; GameObject lastObj = GameObject.Find(last); DestroyImmediate(lastObj); _curEditCellType = EditCellType.None; return; } } Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { GameObject gameObj = hitInfo.collider.gameObject; if (gameObj.layer != LayerMask.NameToLayer("MapCell")) return; string[] point = gameObj.name.Split('_'); if (point.Length != 2) { if (Input.GetMouseButtonUp(1)) { int xx = (int)((gameObj.transform.localPosition.x - _cellWidth / 100.0f / 2) / (_cellWidth / 100.0f)); int yy = (int)((gameObj.transform.localPosition.y - _cellHeight / 100.0f / 2) / (_cellHeight / 100.0f)); UIWindow.Instance.uiNpcsPanel.curActiveList.Remove($"{xx}_{yy}"); DestroyImmediate(gameObj); } return; } int x, y; x = Convert.ToInt32(point[0]); //行 y = Convert.ToInt32(point[1]); //列 CreateSpecialPoint(x, y, type); _curPathObj = gameObj; switch (type) { case EditCellType.ReturnCell: UIWindow.Instance.uiEditMapConfig.txtReturnMapCellPoint.text = gameObj.name.Replace('_', ','); break; case EditCellType.TeleportCell: UIWindow.Instance.uiTeleportPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.NpcCell: UIWindow.Instance.uiNpcsPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.PathNodeCell: UIWindow.Instance.uiCellEditor.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.TriggerCell: UIWindow.Instance.uiTriggersPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.AudioTrigger: UIWindow.Instance.uiAudioTriggerPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.ReliveCell: UIWindow.Instance.uiRelivesPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.SellArea: UIWindow.Instance.uiSellAreasPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.MonsterArea: UIWindow.Instance.uiMonstersPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.FuBenArea: UIWindow.Instance.uiFuBensPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; case EditCellType.JuBaoArea: UIWindow.Instance.uiJuBaosPanel.curActiveInput.text = gameObj.name.Replace('_', ','); break; } } } public void LoadSprite(string spName, GameObject go, int regionWidth=0, int regionHeight=0) { StartCoroutine(LoadSpriteCor(spName, go, regionWidth, regionHeight)); } IEnumerator LoadSpriteCor(string spName, GameObject go, int regionWidth, int regionHeight) { string spPath = PathUtil.GetTexture(_curOpenMapId, spName, "jpg"); using (UnityWebRequest req = UnityWebRequestTexture.GetTexture(spPath)) { yield return req.SendWebRequest(); if (req.result == UnityWebRequest.Result.ConnectionError) { UIWindow.Instance.ShowMessage(req.error); } else { Texture2D tt = DownloadHandlerTexture.GetContent(req); if (tt == null) yield break; //根据获取的Texture建立一个sprite //Sprite sprite = Sprite.Create((Texture2D)tt, new Rect(0, 0, tt.width, tt.height), new Vector2(0, 0)); //sprite.name = spName; //go.GetComponent().sprite = sprite; tt.name = spName; go.GetComponent().texture = tt; go.GetComponent().sizeDelta = new Vector2(regionWidth, regionHeight); } } } }