496 lines
15 KiB
C#
496 lines
15 KiB
C#
using HxGame;
|
|
using HxGame.Data;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.UI;
|
|
|
|
public partial class MapManager : MonoBehaviour
|
|
{
|
|
public enum CellType
|
|
{
|
|
/// <summary>
|
|
/// 无效格
|
|
/// </summary>
|
|
None = 0,
|
|
|
|
/// <summary>
|
|
/// 移动
|
|
/// </summary>
|
|
Move = 1,
|
|
|
|
/// <summary>
|
|
/// 阻挡
|
|
/// </summary>
|
|
Obstacle = 2,
|
|
|
|
/// <summary>
|
|
/// 隐藏
|
|
/// </summary>
|
|
Hide = 4,
|
|
|
|
/// <summary>
|
|
/// 有角色占据(运行时动态变化时产生)
|
|
/// </summary>
|
|
HadRole = 8,
|
|
|
|
/// <summary>
|
|
/// 安全区
|
|
/// </summary>
|
|
Safe = 16,
|
|
|
|
/// <summary>
|
|
/// 摆摊区域
|
|
/// </summary>
|
|
Stall = 32,
|
|
}
|
|
|
|
[Flags]
|
|
public enum CellLayer
|
|
{
|
|
Move = 1, //移动
|
|
Obstacle = 2, //阻挡
|
|
Hide = 4, //隐藏
|
|
Safe = 16, //安全区
|
|
Stall = 32, //摆摊
|
|
Audio = 64, //音效
|
|
Trigger = 128, //触发
|
|
Monster = 256 //怪物
|
|
}
|
|
|
|
|
|
//地图宽高缩放
|
|
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<MapManager>();
|
|
|
|
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<GameObject> gos = new List<GameObject>();
|
|
_layCellsMap.Add(layer, gos);
|
|
}
|
|
|
|
_cellMoveMat = Resources.Load<Material>("Materials/cellMoveMat");
|
|
_cellObsMat = Resources.Load<Material>("Materials/cellObsMat");
|
|
_cellHideMat = Resources.Load<Material>("Materials/cellHideMat");
|
|
_cellDefaultMat = Resources.Load<Material>("Materials/cellDefaultMat");
|
|
|
|
_cellReturnMat = Resources.Load<Material>("Materials/cellReturnMat");
|
|
_cellReliveMat = Resources.Load<Material>("Materials/cellReliveMat");
|
|
_cellTriggerMat = Resources.Load<Material>("Materials/cellTriggerMat");
|
|
_cellTeleportMat = Resources.Load<Material>("Materials/cellTeleportMat");
|
|
_cellNpcMat = Resources.Load<Material>("Materials/cellNpcMat");
|
|
_cellPathNodeMat = Resources.Load<Material>("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<MapConfig.AreaConfig> tempSafeAreasConfig = new List<MapConfig.AreaConfig>();
|
|
|
|
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;
|
|
|
|
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<Image>().sprite = sprite;
|
|
tt.name = spName;
|
|
go.GetComponent<RawImage>().texture = tt;
|
|
go.GetComponent<RectTransform>().sizeDelta = new Vector2(regionWidth, regionHeight);
|
|
}
|
|
}
|
|
}
|
|
}
|