Files
HX_MapEditor/Assets/Scripts/Map/MapManager.cs

496 lines
15 KiB
C#
Raw Normal View History

2025-06-14 13:46:24 +08:00
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>
/// <20><>Ч<EFBFBD><D0A7>
/// </summary>
None = 0,
/// <summary>
/// <20>ƶ<EFBFBD>
/// </summary>
Move = 1,
/// <summary>
/// <20>
/// </summary>
Obstacle = 2,
/// <summary>
/// <20><><EFBFBD><EFBFBD>
/// </summary>
Hide = 4,
/// <summary>
/// <20>н<EFBFBD>ɫռ<C9AB>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>̬<EFBFBD>仯ʱ<E4BBAF><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
HadRole = 8,
/// <summary>
/// <20><>ȫ<EFBFBD><C8AB>
/// </summary>
Safe = 16,
/// <summary>
/// <20><>̯<EFBFBD><CCAF><EFBFBD><EFBFBD>
/// </summary>
Stall = 32,
}
[Flags]
public enum CellLayer
{
Move = 1, //<2F>ƶ<EFBFBD>
Obstacle = 2, //<2F>
Hide = 4, //<2F><><EFBFBD><EFBFBD>
Safe = 16, //<2F><>ȫ<EFBFBD><C8AB>
Stall = 32, //<2F><>̯
Audio = 64, //<2F><>Ч
Trigger = 128, //<2F><><EFBFBD><EFBFBD>
Monster = 256 //<2F><><EFBFBD><EFBFBD>
}
//<2F><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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; //<2F><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private int _maxHeight; //<2F><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD>
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; //<2F>سǵ<D8B3>
private Material _cellReliveMat; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private Material _cellTeleportMat; //<2F><><EFBFBD>͵<EFBFBD>
private Material _cellNpcMat; //npcλ<63><CEBB>
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("<22><><EFBFBD><EFBFBD>cell.prefabʧ<62><CAA7>");
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("<22><><EFBFBD>ȴ򿪵<C8B4>ͼ");
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("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>");
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("<22><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD>ϰ<EFBFBD>ȫ<EFBFBD><C8AB>ö<EFBFBD><C3B6>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//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("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>xml<6D>ɹ<EFBFBD>.");
}
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()
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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]); //<2F><>
y = Convert.ToInt32(point[1]); //<2F><>
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;
//<2F><><EFBFBD>ݻ<EFBFBD>ȡ<EFBFBD><C8A1>Texture<72><65><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>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);
}
}
}
}