格子划分正常

This commit is contained in:
2025-06-15 20:14:45 +08:00
parent c7700419cb
commit bc58a9d0d5
29 changed files with 1546 additions and 107 deletions

View File

@@ -25,7 +25,7 @@ namespace HxGame
private readonly int _index;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD> <20><><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><E8B5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public MapManager.CellType cellType = MapManager.CellType.Obstacle;
public CellType cellType = CellType.Obstacle;
public int X { get { return _x; } }
public int Y { get { return _y; } }
@@ -55,14 +55,14 @@ namespace HxGame
return new Vector3(x, 0.03f, z);
}
public CellNode(int x, int y, int index, MapManager.CellType type)
public CellNode(int x, int y, int index, CellType type)
{
_x = x;
_y = y;
_index = index;
if (type == MapManager.CellType.Safe)
cellType |= MapManager.CellType.Safe;
if (type == CellType.Safe)
cellType |= CellType.Safe;
else
cellType = type;
}

View File

@@ -0,0 +1,501 @@
using UnityEngine;
using UnityEngine.EventSystems;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System;
//[ExecuteAlways]
public class GridSelector : MonoBehaviour
{
public struct RenderData
{
public int barrier; //阻隔点,高度值
public float isSelected;
public float r;
public float g;
public float b;
}
[Space]
[Range(0f, 1f)]
[Header("调整透明度")]
public float gridAlpha = 1;
private MeshRenderer mapRenderer;
private MeshCollider mapCollider;
private Map map;
public int horizontalNumber { get { return Mathf.CeilToInt(map.width / map.sideWidth); } }
public int verticalNumber { get { return Mathf.CeilToInt(map.height / map.sideHeight); } }
public int totalNumber { get { return horizontalNumber * verticalNumber; } }
private ComputeBuffer inputbuffer;
private RenderData[] dataArray;
private List<int> selectedGridIndex = new List<int>();
private int shiftBeginIndex;
private List<Vector2> lassoPos = new List<Vector2>();
private LineRenderer lassoLine;
public CellType CellType { set; get; }
public void OnMapCreated(Map map)
{
this.map = map;
mapRenderer.material.SetVector("_Size", new Vector4(horizontalNumber, verticalNumber));
mapRenderer.material.SetFloat("_UserInput", 1);
inputbuffer = new ComputeBuffer(totalNumber, Marshal.SizeOf(typeof(RenderData)));
dataArray = new RenderData[totalNumber];
//创建新的地图默认为全部是可行走区域
for (int i = 0; i < totalNumber; i++)
{
dataArray[i].barrier = (int)CellType.None;
}
RefreshPlaneRender();
}
public RenderData[] GetGridData()
{
return dataArray;
}
public void setdataArrayIndex(int index,float cellheight, int barrier)
{
if (index >= dataArray.Length)
return;
int height = (int)(cellheight * 100);
height += 10000;
int mask = dataArray[index].barrier & 0xFFFF;
//去除之前的8-16位
//mask &= 0xFF;
//移除之前的信息值再加新的
mask &= ~(int)CellType.Move;
mask &= ~(int)CellType.Obstacle;
mask |= barrier;
//先取出之前的高度值
dataArray[index].barrier = height << 16;
dataArray[index].barrier |= mask;
setDataColor(index);
}
public int getdataByPos(Vector3 pos)
{
int hitIndex = Mathf.FloorToInt(pos.x / map.sideLength) + Mathf.FloorToInt(pos.z / map.sideLength) * horizontalNumber;
return hitIndex;
}
private void Awake()
{
mapRenderer = GetComponent<MeshRenderer>();
mapCollider = GetComponent<MeshCollider>();
GameObject go = GameObject.Instantiate(MapManager.Instance.line.gameObject);
go.transform.SetParent(transform);
lassoLine = go.GetComponent<LineRenderer>();
lassoLine.positionCount = 0;
lassoLine.startWidth = 0.1f;
lassoLine.endWidth = 0.1f;
lassoLine.gameObject.SetActive(false);
}
private void OnDestroy()
{
if (inputbuffer != null)
{
inputbuffer.Release();
}
}
private int GetIndexByXY(int x, int y) {
int index = x + y * horizontalNumber;
return index;
}
/// <summary>
/// 这里采用的算法是每行从左到右的算法,但是过滤了已经重复过的格子
/// *************
/// *****678*****
/// *****4*5*****
/// *****123*****
/// *************
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
private int FindMapHeight(int index) {
GetXyByIndex(index, out int oldx, out int oldy);
//像外扩展,找到一个邻近的高度值
int maxR = 1000;
int stepI;
for (int r = 1; r < maxR; r++)
{
for (int j = -r; j <= r; j++)
{
if (j == -r || j == r)
{
stepI = 1;
}
else
{
stepI = r * 2;
}
for (int i = -r; i <= r; i += stepI)
{
int x = oldx + i;
int y = oldy + j;
if (x < 0 || x >= horizontalNumber || y < 0 || y >= verticalNumber) {
continue;
}
int neighborIndex = x + y * horizontalNumber;
int neighborValue = dataArray[neighborIndex].barrier;
if (neighborValue != 0)
{
return neighborValue;
}
}
}
}
return 1;
}
float lastAlpha = 1;
private void Update()
{
if (lastAlpha != gridAlpha)
{
map.ChangeGridAlpha(gridAlpha);
lastAlpha = gridAlpha;
}
//先处理移动区域,要先处理之前的区域数据
if (Input.GetKeyDown(KeyCode.C))
{
for (int i = 0, length = selectedGridIndex.Count; i < length; i++)
{
int index = selectedGridIndex[i];
//if ((dataArray[index].barrier & (int)CellType.Obstacle) != 0)
//{
// dataArray[index].barrier &= ~(int)CellType.Obstacle;
//}
//dataArray[index].barrier |= (int)CellType.Move;
setDataCellType(index, true);
}
RefreshPlaneRender();
}
if (Input.GetKeyDown(KeyCode.X))
{
for (int i = 0, length = selectedGridIndex.Count; i < length; i++)
{
int index = selectedGridIndex[i];
//if ((dataArray[index].barrier & (int)CellType.Move) != 0)
//{
// dataArray[index].barrier &= ~(int)CellType.Move;
//}
//dataArray[index].barrier |= (int)CellType.Obstacle;
setDataCellType(index, false);
}
RefreshPlaneRender();
}
if (Input.GetKeyUp(KeyCode.Z))
{
lassoPos.Clear();
lassoLine.gameObject.SetActive(false);
lassoLine.positionCount = 0;
}
if (Input.GetMouseButtonDown(0))
{
if (mapCollider.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, float.PositiveInfinity))
{
Vector2 hitUv = hit.textureCoord;
int hitIndex = Mathf.FloorToInt(hitUv.x * horizontalNumber) + Mathf.FloorToInt(hitUv.y * verticalNumber) * horizontalNumber;
if (!Input.GetKey(KeyCode.LeftShift))
{
if (Input.GetKey(KeyCode.LeftControl))
{
shiftBeginIndex = hitIndex;
SetGridIndexSelected(hitIndex, dataArray[hitIndex].isSelected != 1f);
RefreshPlaneRender();
}
else if (Input.GetKey(KeyCode.Z))
{
Vector2 hitPos = GetCenterPosByIndex(hitIndex);
if (lassoPos.Count == 0 || lassoPos[0] != hitPos)
{
if (lassoPos.Count == 0)
{
SetAllUnselected();
}
SetGridIndexSelected(hitIndex, true);
lassoLine.gameObject.SetActive(true);
lassoLine.positionCount++;
lassoLine.SetPosition(lassoLine.positionCount - 1, new Vector3(hitPos.x,transform.position.y + 0.1f, hitPos.y));
lassoPos.Add(hitPos);
}
else
{
lassoLine.positionCount++;
lassoLine.SetPosition(lassoLine.positionCount - 1, new Vector3(hitPos.x,transform.position.y + 0.1f, hitPos.y));
lassoPos.Add(hitPos);
for (int i = 0; i < totalNumber; i++)
{
Vector2 gridPos = GetCenterPosByIndex(i);
bool isSelected = false;
for (int j = 0, length = lassoPos.Count - 1; j < length; j++)
{
Vector2 pos0 = lassoPos[j];
Vector2 pos1 = lassoPos[j + 1];
if (Pnpoly(gridPos, pos0, pos1))
{
isSelected = !isSelected;
}
}
SetGridIndexSelected(i, isSelected);
}
}
if (lassoLine.positionCount == 2)
{
//CSSMoveMgr.Instance.FindPath(lassoPos[0], lassoPos[1]);
//在这里寻找路径
}
RefreshPlaneRender();
}
else if (!Input.GetKey(KeyCode.LeftAlt)) //左alt键涉及到镜头操作所以屏蔽掉
{
shiftBeginIndex = hitIndex;
SetAllUnselected();
SetGridIndexSelected(hitIndex, true);
RefreshPlaneRender();
}
}
}
else
{
SetAllUnselected();
RefreshPlaneRender();
}
}
else if (Input.GetMouseButton(0))
{
if (mapCollider.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, float.PositiveInfinity))
{
if (Input.GetKey(KeyCode.LeftShift))
{
Vector2 hitUv = hit.textureCoord;
int hitIndex = Mathf.FloorToInt(hitUv.x * horizontalNumber) + Mathf.FloorToInt(hitUv.y * verticalNumber) * horizontalNumber;
int beginX, beginY;
GetXyByIndex(shiftBeginIndex, out beginX, out beginY);
int hitX, hitY;
GetXyByIndex(hitIndex, out hitX, out hitY);
beginPos.x = beginX;
beginPos.z = beginY;
endPos.x = hitX;
endPos.z = hitY;
//CSSMoveMgr.Instance.FindPath(new Vector3(beginX,0,beginY),new Vector3(hitX,0,hitY));
ShiftKeySelect(hitIndex);
RefreshPlaneRender();
}
}
}
}
private Vector3 beginPos = new Vector3();
private Vector3 endPos = new Vector3();
private void OnGUI()
{
GUIStyle style = new GUIStyle() { fontSize = 30 };
style.normal.textColor = Color.red;
int width = Screen.width;
int height = Screen.height;
GUI.Label(new Rect(width - 320, height - 150, 400, 50), "按住Shift按钮多选", style);
GUI.Label(new Rect(width - 320, height - 100, 400, 50), "选中后C键取消格子信息", style);
GUI.Label(new Rect(width - 320, height - 50, 400, 50), "选中后X键确定格子信息", style);
style.normal.textColor = Color.green;
if (selectedGridIndex.Count == 0)
{
return;
}
else if (selectedGridIndex.Count == 1)
{
int beginIndex = selectedGridIndex[0];
GetXyByIndex(beginIndex, out int x, out int y);
string labelText = string.Format(
"所选点XY序列({0},{1})",
x, y);
Vector2 labelSize = style.CalcSize(new GUIContent(labelText));
GUI.Label(
new Rect(Screen.width - labelSize.x - 20, 20, labelSize.x, labelSize.y),
labelText,
style
);
//GUI.Label(new Rect(width - 820, 20, 400, 50), string.Format("所选点XY序列({0},{1}) 高度{2} 点类型 {3}", x, y, ((dataArray[beginIndex].barrier >> 16) - 10000)/100.0f, CellTypeColors.GetAreaStr((dataArray[beginIndex].barrier)), style));
}
else
{
int beginIndex = selectedGridIndex[0];
int endIndex = selectedGridIndex[selectedGridIndex.Count - 1];
GetXyByIndex(beginIndex, out int x0, out int y0);
GetXyByIndex(endIndex, out int x1, out int y1);
GUI.Label(new Rect(width - 420, 20, 400, 50), string.Format("所选起点XY序列({0},{1})", x0, y0), style);
GUI.Label(new Rect(width - 420, 90, 400, 50), string.Format("所选终点XY序列({0},{1})", x1, y1), style);
}
}
private void SetGridIndexSelected(int index, bool isSelected)
{
if (isSelected)
{
if (!selectedGridIndex.Contains(index))
{
selectedGridIndex.Add(index);
dataArray[index].isSelected = 1f;
}
}
else
{
selectedGridIndex.Remove(index);
dataArray[index].isSelected = 0f;
}
}
private void setDataColor(int index) {
Color color = CellTypeColors.GetColor((CellType)dataArray[index].barrier);
dataArray[index].r = color.r;
dataArray[index].g = color.g;
dataArray[index].b = color.b;
}
private void setDataCellType(int index,bool IsCancel)
{
if (true)
{
if (IsCancel)
{
if ((dataArray[index].barrier & (int)CellType.Obstacle) != 0)
{
dataArray[index].barrier &= ~(int)CellType.Obstacle;
}
dataArray[index].barrier |= (int)CellType.Move;
}
else
{
if ((dataArray[index].barrier & (int)CellType.Move) != 0)
{
dataArray[index].barrier &= ~(int)CellType.Move;
}
dataArray[index].barrier |= (int)CellType.Obstacle;
}
}
else if (true)
{
if (IsCancel)
{
if ((dataArray[index].barrier & (int)CellType.Safe) != 0)
{
dataArray[index].barrier &= ~(int)CellType.Safe;
}
}
else
{
dataArray[index].barrier |= (int)CellType.Safe;
}
}
else if (true)
{
if (IsCancel)
{
if ((dataArray[index].barrier & (int)CellType.Stall) != 0)
{
dataArray[index].barrier &= ~(int)CellType.Stall;
}
}
else
{
dataArray[index].barrier |= (int)CellType.Stall;
}
}
}
public void RefreshPlaneRender()
{
int runNum = 0;
for (int i = 0; i < dataArray.Length; i++) {
//int barrier = dataArray[i].barrier;
setDataColor(i);
CellType cell = (CellType)dataArray[i].barrier;
if (cell.HasFlag(CellType.Move))
{
runNum++;
}
}
inputbuffer.SetData(dataArray);
mapRenderer.material.SetBuffer("_InputData", inputbuffer);
}
private void GetXyByIndex(int index,out int x,out int y)
{
x = index % horizontalNumber;
y = index / horizontalNumber;
}
private Vector2 GetCenterPosByIndex(int index)
{
GetXyByIndex(index, out int x, out int y);
return new Vector2(x + 0.5f, y + 0.5f) * map.sideLength;
}
private bool Pnpoly(Vector2 gridPos, Vector2 pos0, Vector2 pos1)
{
bool tmp0 = (gridPos.y < pos1.y) != (gridPos.y < pos0.y);
bool tmp1 = gridPos.x <= (pos0.x - pos1.x) * (gridPos.y - pos1.y) / (pos0.y - pos1.y) + pos1.x;
return tmp0 && tmp1;
}
private void SetAllUnselected()
{
for (int i = selectedGridIndex.Count - 1; i >= 0; i--)
{
SetGridIndexSelected(selectedGridIndex[i], false);
}
}
private void ShiftKeySelect(int hitIndex)
{
int beginX, beginY;
GetXyByIndex(shiftBeginIndex, out beginX, out beginY);
int hitX, hitY;
GetXyByIndex(hitIndex, out hitX, out hitY);
int minX = Mathf.Min(beginX, hitX);
int maxX = Mathf.Max(beginX, hitX);
int minY = Mathf.Min(beginY, hitY);
int maxY = Mathf.Max(beginY, hitY);
shiftBeginIndex = hitIndex;
for (int y = 0; y < verticalNumber; y++)
{
for (int x = 0; x < horizontalNumber; x++)
{
bool isWithin = x >= minX && x <= maxX && y >= minY && y <= maxY;
if (isWithin)
{
int index = x + y * horizontalNumber;
SetGridIndexSelected(index, true);
}
}
}
}
public Vector2Int GetMouseByCell()
{
Vector2Int cell = new Vector2Int();
if (mapCollider.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, float.PositiveInfinity))
{
Vector2 hitUv = hit.textureCoord;
cell.x = Mathf.FloorToInt(hitUv.x * horizontalNumber);
cell.y = Mathf.FloorToInt(hitUv.y * verticalNumber);
}
return cell;
}
public Vector2Int GetMouseByCell(Vector3 mousePositon)
{
Vector2Int cell = new Vector2Int();
if (mapCollider.Raycast(Camera.main.ScreenPointToRay(mousePositon), out RaycastHit hit, float.PositiveInfinity))
{
Vector2 hitUv = hit.textureCoord;
cell.x = Mathf.FloorToInt(hitUv.x * horizontalNumber);
cell.y = Mathf.FloorToInt(hitUv.y * verticalNumber);
}
return cell;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98e7367499fcb314f8c04a4d6aaca75c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
using System;
using UnityEngine;
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>
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
/// </summary>
public class AreaColor
{
public static Color Monster = Color.red;
public static Color Npc = Color.yellow;
public static Color Stall = Color.magenta;
public static Color Relive = Color.green;
public static Color Audio = Color.white;
public static Color Trans = Color.blue;
public static Color Born = Color.green;
}
public class CellTypeColors
{
public static Color None = new Color(0x80 / 255f, 0x80 / 255f, 0x80 / 255f); // <20><>ɫ (#808080)
public static Color Move = new Color(0x33 / 255f, 0xcc / 255f, 0x33 / 255f); // <20><>ɫ (#33cc33)
public static Color Obstacle = new Color(0xff / 255f, 0x00 / 255f, 0x00 / 255f); // <20><>ɫ (#ff4d4d)
public static Color Hide = new Color(0x33 / 255f, 0x33 / 255f, 0x33 / 255f); // <20><><EFBFBD><EFBFBD>ɫ (#333333)
public static Color HadRole = new Color(0xb3 / 255f, 0x33 / 255f, 0xb3 / 255f); // <20><>ɫ (#b333b3)
public static Color Safe = new Color(0x00 / 255f, 0xff / 255f, 0xff / 255f); // <20><>ɫ (#00ffff)
public static Color Stall = new Color(0xff / 255f, 0xff / 255f, 0x99 / 255f); // dz<><C7B3>ɫ (#ffff99)
public static Color Water = new Color(0x00 / 255f, 0x4c / 255f, 0xb3 / 255f); // ˮ<><CBAE>ɫ (#004cb3)
public static Color Snow = new Color(0xff / 255f, 0xff / 255f, 0xff / 255f); // <20><>ɫ (#ffffff)
public static Color Sand = new Color(0xff / 255f, 0xcc / 255f, 0x66 / 255f); // ɳ<><C9B3>ɫ (#ffcc66)
public static Color Stone = new Color(0x66 / 255f, 0x66 / 255f, 0x66 / 255f); // <20><><EFBFBD><EFBFBD>ɫ (#666666)
public static Color Wood = new Color(0x8B / 255f, 0x45 / 255f, 0x13 / 255f); // <20><>ɫ (#8B4513)
public static Color Grass = new Color(0x00 / 255f, 0xff / 255f, 0xff / 255f); // <20><>ɫ (#00ffff)
public static Color Dirt = new Color(0xff / 255f, 0x49 / 255f, 0x00 / 255f); // dz<><C7B3>ɫ (#FF4900)
public static Color GetColor(CellType cellType)
{
Color color = Color.clear; // <20><>ʼ<EFBFBD><CABC>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
if (cellType == CellType.None) return CellTypeColors.None;
if (true)
{
if (cellType.HasFlag(CellType.Move)) color += CellTypeColors.Move;
}
else if (true)
{
if (cellType.HasFlag(CellType.Safe)) color += CellTypeColors.Safe;
}
else if (true)
{
if (cellType.HasFlag(CellType.Stall)) color += CellTypeColors.Stall;
}
if (cellType.HasFlag(CellType.Obstacle)) color += CellTypeColors.Obstacle;
// <20><><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ,<2C>Ȳ<EFBFBD><C8B2><EFBFBD>һ<EFBFBD><D2BB>
//color /= 7.0f; // 7 <20><> CellType <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return color;
}
public static string GetAreaStr(int barrier)
{
string areaStr = " ";
CellType cellType = (CellType)(barrier & 0xffff);
if (cellType == CellType.None)
{
areaStr = "<22><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>";
return areaStr;
}
if (cellType.HasFlag(CellType.Move)) areaStr += "<22><><EFBFBD>ƶ<EFBFBD>";
if (cellType.HasFlag(CellType.Obstacle)) areaStr += "|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
if (cellType.HasFlag(CellType.Safe)) areaStr += "|<7C><>ȫ<EFBFBD><C8AB>";
if (cellType.HasFlag(CellType.Stall)) areaStr += "|<7C><>̯<EFBFBD><CCAF>";
return areaStr;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b97c6c8681e73ad44aef35c1b2703db8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class MapManager : MonoBehaviour
{
private float moveSpeed = 10;
private float mapRealWidth;
private float mapRealHeight;
private Vector3 lastMousePosition;
private void UpdateCamera()
{
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize + Time.deltaTime * moveSpeed * Camera.main.orthographicSize, 5, 40);
}
else if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize - Time.deltaTime * moveSpeed * Camera.main.orthographicSize, 5, 40);
}
// <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC>϶<EFBFBD>ƽ<EFBFBD><C6BD>
if (Input.GetMouseButtonDown(2)) // <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD>
{
lastMousePosition = Input.mousePosition;
}
else if (Input.GetMouseButton(2)) // <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD>ס
{
Vector3 delta = Input.mousePosition - lastMousePosition;
Vector3 move = new Vector3(-delta.x, -delta.y, 0) * Time.deltaTime * Camera.main.orthographicSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD>ٶ<EFBFBD>
Vector3 newPosition = Camera.main.transform.position + move;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ͼ<EFBFBD>߽磩
newPosition.x = Mathf.Clamp(newPosition.x, 0, mapRealWidth);
newPosition.y = Mathf.Clamp(newPosition.y, 0, mapRealHeight);
Camera.main.transform.position = newPosition;
lastMousePosition = Input.mousePosition; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
}
}
private void ReseCamera(float x, float y)
{
Camera.main.transform.position = new Vector3(x / 2, y / 2, -10);
Camera.main.orthographicSize = 5;
mapRealWidth = x;
mapRealHeight = y;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 970e1f87354a1674db60e09afc2752ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -3,9 +3,14 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Xml;
using System.Xml.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;
using static MapManager;
public partial class MapManager : MonoBehaviour
@@ -18,8 +23,8 @@ public partial class MapManager : MonoBehaviour
return false;
}
string path = string.Empty;
string path = string.Empty;
path = PathUtil.GetXmlPath(_curOpenMapId, "Obs");
if (!File.Exists(path))
@@ -50,14 +55,14 @@ public partial class MapManager : MonoBehaviour
//0,0,1,0;0,1,1,1;0,2,1,2;
string[] values = strData.Split(';');
if(values.Length != cellCount)
if (values.Length != cellCount)
{
UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>");
return false;
}
cellsNode = new CellNode[cellCount];
for (int i=0; i<cellCount; i++)
for (int i = 0; i < cellCount; i++)
{
string[] strCell = values[i].Split(',');
@@ -78,4 +83,56 @@ public partial class MapManager : MonoBehaviour
return true;
}
public void LoadMapSprite()
{
//map<61><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
GameObject map = new GameObject("map");
int mapRownum = 11;
int mapColumn = 14;
//ƽ<><C6BD>;
float jpgscenew = 512f / 100;
for (int row = 0; row < mapRownum; row++)
{
for (int col = 0; col < mapColumn; col++)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>v1000_r1_c1.jpg
string filename = $"v{1000}_r{row + 1}_c{col + 1}";
string spPath = PathUtil.GetMapTexure(1000, filename, "jpg");
GameObject obj = new GameObject(filename);
obj.transform.SetParent(map.transform);
SpriteRenderer sr = obj.AddComponent<SpriteRenderer>();
float x = col * jpgscenew;
float y = (mapRownum - row - 1) * jpgscenew;
obj.transform.position = new Vector2(x, y);
StartCoroutine(LoadSpriteT(spPath, obj,sr));
// ֱ<><D6B1>ʹ<EFBFBD><CAB9>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sprite
//sr.sprite = Sprite.Create(asset, new Rect(0, 0, asset.width, asset.height), Vector2.zero, 100f);
//float x = col * jpgscenew;
//float y = (mapRownum - row - 1) * jpgscenew;
//obj.transform.position = new Vector2(x, y);
//Debug.Log($"Tile {filename} placed at ({x}, {y})");
}
}
MapManager.Instance.ReseCamera(jpgscenew * mapColumn, jpgscenew * mapRownum);
MapManager.Instance.GenerateMap(jpgscenew * mapColumn, jpgscenew * mapRownum, 0.48f, 0.32f);
}
IEnumerator LoadSpriteT(string spName, GameObject go, SpriteRenderer sprite)
{
using (UnityWebRequest req = UnityWebRequestTexture.GetTexture(spName))
{
yield return req.SendWebRequest();
if (req.result == UnityWebRequest.Result.Success)
{
Texture2D tt = DownloadHandlerTexture.GetContent(req);
if (tt == null)
yield break;
sprite.sprite = Sprite.Create(tt, new Rect(0, 0, tt.width, tt.height), Vector2.zero, 100f);
}
else
{
UIWindow.Instance.ShowMessage(req.error);
}
}
}
}

View File

@@ -0,0 +1,181 @@
using UnityEngine;
using System.IO;
using UnityEditor;
using System;
//[ExecuteAlways]
public partial class MapManager : MonoBehaviour
{
public Material gridMat;
//public ComputeShader computeShader;
public LineRenderer line;
public Map map { get; private set; }
public event Action onMapCreated;
public CellType cellType;
public Map GenerateMap(float width, float height,float sideWidth, float sideHeight)
{
if (map != null)
{
map.Release();
map = null;
}
map = new Map(width, height, sideWidth, sideHeight);
map.SetMapId(1000);
//默认设置半透明0.3
map.ChangeGridAlpha(0.4f);
onMapCreated?.Invoke();
return map;
}
public void ChangeGridAlpha(float alpha)
{
if (map == null)
{
return;
}
map.ChangeGridAlpha(alpha);
}
public void ChangeGridHeight(float height)
{
if (map == null)
{
return;
}
int spaceHight = (int)Math.Ceiling(height * 100); //4米为一档
map.ChangeGridHight(spaceHight);
}
public void ShowOrHideGrid()
{
if (map == null)
return;
map.mapGrid.gameObject.SetActive(!map.mapGrid.activeInHierarchy);
}
/// <summary>
/// 获取地图位置的高度
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public int GetMapY(Vector3 pos)
{
int posIndex = Mathf.FloorToInt(pos.x + Mathf.FloorToInt(pos.z) * map.horizontalNumber);
return map.selector.GetGridData()[posIndex].barrier;
}
}
public partial class Map
{
public GameObject mapGrid;
public GridSelector selector;
public int mapId { get; private set; }
public float width { get; private set; }
public float height { get; private set; }
public float sideLength { get; private set; }
public float sideWidth { get; private set; }
public float sideHeight { get; private set; }
public int horizontalNumber { get { return (int)(width / sideWidth); } }
public int verticalNumber { get { return (int)(height / sideHeight); } }
public Map(float width, float height, float sideWidth,float sideHeight)
{
this.width = width;
this.height = height;
this.sideLength = sideLength;
this.sideWidth = sideWidth;
this.sideHeight = sideHeight;
mapGrid = CreateMapGrid();
selector = mapGrid.AddComponent<GridSelector>();
selector.OnMapCreated(this);
mapGrid.transform.parent = MapManager.Instance.transform;
mapGrid.transform.localPosition = Vector3.zero;
mapGrid.transform.localEulerAngles = new Vector3(-90,0,0);
//创建地图的时候需要赋值一下当前类型
selector.CellType = MapManager.Instance.cellType;
}
private GameObject CreateMapGrid()
{
Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(0f, 0f, 0f);
vertices[1] = new Vector3(0f, 0f, height);
vertices[2] = new Vector3(width, 0f, height);
vertices[3] = new Vector3(width, 0f, 0f);
mesh.vertices = vertices;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(0, 1);
uv[2] = new Vector2(1, 1);
uv[3] = new Vector2(1, 0);
mesh.uv = uv;
int[] triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
mesh.triangles = triangles;
Vector3[] normals = new Vector3[4] { Vector3.up, Vector3.up, Vector3.up, Vector3.up };
mesh.normals = normals;
GameObject go = new GameObject("Grid");
go.AddComponent<MeshFilter>().mesh = mesh;
go.AddComponent<MeshRenderer>().sharedMaterial = MapManager.Instance.gridMat;
go.AddComponent<MeshCollider>().sharedMesh = mesh;
return go;
}
public void SetMapId(int mapId)
{
this.mapId = mapId;
}
public void ChangeGridAlpha(float alpha)
{
mapGrid.GetComponent<MeshRenderer>().material.SetFloat("_Alpha", alpha);
}
public void ChangeGridHight(int height)
{
mapGrid.transform.position = new Vector3(0, height,0);
}
public void Release()
{
GameObject.Destroy(mapGrid);
mapGrid = null;
}
public static void Serialize(Map map, BinaryWriter bw)
{
int width = map.selector.horizontalNumber;
int height = map.selector.verticalNumber;
int sideLength = (int)(map.sideLength * 100);
bw.Write(map.mapId);
bw.Write(width);
bw.Write(height);
bw.Write(sideLength);
GridSelector.RenderData[] data = map.selector.GetGridData();
for (int i = 0, length = data.Length; i < length; i++)
{
bw.Write(data[i].barrier);
}
Debug.Log("地图保存成功");
}
public static Map Deserialize(BinaryReader br)
{
int mapId = br.ReadInt32();
int horizontalNumber = br.ReadInt32();
int verticalNumber = br.ReadInt32();
//服务器那边是用的边长的100倍的int
float sideWidth = br.ReadInt32() / 100f;
float sideHeight = br.ReadInt32() / 100f;
var map = MapManager.Instance.GenerateMap((int)(horizontalNumber * sideWidth), (int)(verticalNumber * sideHeight), sideWidth, sideHeight);
map.SetMapId(mapId);
GridSelector.RenderData[] data = map.selector.GetGridData();
for (int i = 0; i < horizontalNumber * verticalNumber; i++) {
data[i].barrier = br.ReadInt32();
}
map.selector.RefreshPlaneRender();
return map;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a6b534287916c3e46b9fca4552637f0b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,67 +6,13 @@ 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.Tilemaps;
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;
@@ -75,6 +21,7 @@ public partial class MapManager : MonoBehaviour
//public delegate void CloseMapCallback();
//public CloseMapCallback onCloseMapCallback;
private static MapManager _mapManager = null;
public static MapManager Instance
{
@@ -290,7 +237,7 @@ public partial class MapManager : MonoBehaviour
bool bHoverUI = EventSystem.current != null && EventSystem.current.IsPointerOverGameObject();
if (bHoverUI)
return;
UpdateCamera();
if (_curEditCellType != EditCellType.None)
{
EditSpecialMapPoint(_curEditCellType);

View File

@@ -324,7 +324,7 @@ namespace HxGame.PathFinding
mNewLocation = (mNewLocationY << mGridYLog2) + mNewLocationX;
CellNode nextCell = mGrid[mNewLocation];
if (nextCell == null || (nextCell.cellType == MapManager.CellType.Obstacle && !mIgnoreCanCrossCheck))
if (nextCell == null || (nextCell.cellType == CellType.Obstacle && !mIgnoreCanCrossCheck))
continue;
//if (!mIncludeInvisibleCells && !mGrid[mNewLocation].visible)

View File

@@ -302,7 +302,7 @@ namespace HxGame.PathFinding
continue;
mNewLocation = (mNewLocationY * mGridX) + mNewLocationX;
if (mGrid[mNewLocation].cellType == MapManager.CellType.Obstacle && !mIgnoreCanCrossCheck)
if (mGrid[mNewLocation].cellType == CellType.Obstacle && !mIgnoreCanCrossCheck)
{
Debug.Log($"{mNewLocation}<7D><><EFBFBD><EFBFBD><E8B5B2>");
continue;

View File

@@ -194,7 +194,7 @@ public class UICellEditor : MonoBehaviour
//ͼ<><CDBC><EFBFBD>
public void OnShowLayerToggleChange()
{
MapManager.CellLayer[] layers = (MapManager.CellLayer[])Enum.GetValues(typeof(MapManager.CellLayer));
CellLayer[] layers = (CellLayer[])Enum.GetValues(typeof(CellLayer));
_layers = 0;
for (int i= showgLayers.Length - 1; i>=0; i--)
{
@@ -223,7 +223,7 @@ public class UICellEditor : MonoBehaviour
}
float brushRadius = Convert.ToSingle(txtBrushRadius.text);
MapManager.CellType type = (MapManager.CellType)(1 << dropCellType.value);
CellType type = (CellType)(1 << dropCellType.value);
MapManager.Instance.SetBrush(brushRadius, type);
MapManager.Instance.StartEditor();
}

View File

@@ -97,7 +97,7 @@ public class UICellInfo : MonoBehaviour
UIWindow.Instance.uiCreateMap.MapBG.GetComponent<CanvasGroup>().blocksRaycasts = false;
MapManager.Instance.CreateCells();
txtMoveCells.text = MapManager.Instance.GetLayCellCount(MapManager.CellLayer.Move).ToString();
txtMoveCells.text = MapManager.Instance.GetLayCellCount(CellLayer.Move).ToString();
}
public void HideCells()

View File

@@ -53,17 +53,17 @@ public class UICreateMap : MonoBehaviour
return false;
}
if (string.IsNullOrEmpty(txtMapWidth.text))
{
UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>");
return false;
}
//if (string.IsNullOrEmpty(txtMapWidth.text))
//{
// UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>");
// return false;
//}
if (string.IsNullOrEmpty(txtMapHeight.text))
{
UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ͼ<EFBFBD>߶<EFBFBD>");
return false;
}
//if (string.IsNullOrEmpty(txtMapHeight.text))
//{
// UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ͼ<EFBFBD>߶<EFBFBD>");
// return false;
//}
if (string.IsNullOrEmpty(txtRegionWidth.text))
{
@@ -78,12 +78,12 @@ public class UICreateMap : MonoBehaviour
}
int mapId = Convert.ToInt32(txtMapID.text);
int mapWidth = Convert.ToInt32(txtMapWidth.text);
int mapHeight = Convert.ToInt32(txtMapHeight.text);
//int mapWidth = Convert.ToInt32(txtMapWidth.text);
//int mapHeight = Convert.ToInt32(txtMapHeight.text);
int regionWidth = Convert.ToInt32(txtRegionWidth.text);
int regionHeight = Convert.ToInt32(txtRegionHeight.text);
if (mapWidth <= 0 || mapHeight <= 0 || regionWidth <= 0 || regionHeight <= 0)
if (regionWidth <= 0 || regionHeight <= 0)
{
UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>ֵ");
return false;

View File

@@ -93,6 +93,7 @@ public class UIMapPanel : MonoBehaviour
UIWindow.Instance.uiJuBaosPanel.LoadJuBaoConfig(mapId);
_curOpenMapId = mapId;
//MapManager.Instance.LoadMapSprite();
}
public void CloseMap()

View File

@@ -9,6 +9,11 @@ public class PathUtil
return $"{Application.dataPath}/GameAssets/Maps/{mapId}/Texture/{name}.{suffix}";
}
public static string GetMapTexure(int mapId, string name, string suffix)
{
return $"{Application.dataPath}/GameAssets/Maps/{mapId}/Texture/{name}.{suffix}";
}
#region XML