Files
aibis-dream/Assets/Scripts/MiniGame/BlockPuzzle/Class/GridVisualizer.cs
T
2025-11-27 18:14:24 +08:00

338 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using UnityEngine;
namespace AibisDream
{
/// <summary>
/// 网格可视化组件
/// 负责在Unity场景中可视化显示网格和单元格状态
/// </summary>
public class GridVisualizer : MonoBehaviour
{
[Header("网格配置")]
[SerializeField] private BlockPuzzleGrid gridComponent;
[SerializeField] private int gridWidth = 10;
[SerializeField] private int gridHeight = 10;
[SerializeField] private float cellSize = 1f;
private IBlockPuzzleGrid _grid;
[Header("可视化设置")]
[SerializeField] private bool showGridLines = true;
[SerializeField] private bool showCellSprites = true;
[SerializeField] private Color emptyCellColor = new Color(0.9f, 0.9f, 0.9f, 0.3f);
[SerializeField] private Color occupiedCellColor = new Color(0.2f, 0.6f, 1f, 1f);
[SerializeField] private Color gridLineColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
[SerializeField] private float gridLineWidth = 0.02f;
[Header("预制体(可选)")]
[SerializeField] private Sprite cellSprite;
[SerializeField] private Material cellMaterial;
// 单元格可视化对象池
private Dictionary<(int x, int y), GameObject> _cellObjects = new Dictionary<(int x, int y), GameObject>();
private GameObject _gridLinesParent;
private GameObject _cellsParent;
private BlockPuzzleGrid _internalGrid;
private void Awake()
{
// 创建父对象用于组织层级
_gridLinesParent = new GameObject("GridLines");
_gridLinesParent.transform.SetParent(transform);
_gridLinesParent.transform.localPosition = Vector3.zero;
_cellsParent = new GameObject("Cells");
_cellsParent.transform.SetParent(transform);
_cellsParent.transform.localPosition = Vector3.zero;
}
private void Start()
{
InitializeGrid();
}
/// <summary>
/// 初始化网格
/// </summary>
public void InitializeGrid()
{
// 优先使用外部网格组件
if (gridComponent != null)
{
// 如果组件还没有初始化,先初始化它
if (!gridComponent.IsInitialized())
{
gridComponent.Initialize();
}
_grid = gridComponent;
}
else
{
// 如果没有外部网格,创建内部网格组件
if (_internalGrid == null)
{
_internalGrid = gameObject.GetComponent<BlockPuzzleGrid>();
if (_internalGrid == null)
{
_internalGrid = gameObject.AddComponent<BlockPuzzleGrid>();
}
}
_internalGrid.Initialize(gridWidth, gridHeight, cellSize, transform.position);
_grid = _internalGrid;
}
CreateVisualization();
}
/// <summary>
/// 设置网格引用
/// </summary>
public void SetGrid(IBlockPuzzleGrid grid)
{
_grid = grid;
ClearVisualization();
CreateVisualization();
}
/// <summary>
/// 创建可视化
/// </summary>
private void CreateVisualization()
{
if (_grid == null) return;
if (showGridLines)
{
DrawGridLines();
}
if (showCellSprites)
{
CreateCellSprites();
}
}
/// <summary>
/// 绘制网格线
/// </summary>
private void DrawGridLines()
{
// 清除旧的网格线
foreach (Transform child in _gridLinesParent.transform)
{
if (Application.isPlaying)
{
Destroy(child.gameObject);
}
else
{
DestroyImmediate(child.gameObject);
}
}
// 创建网格线(使用LineRenderer或简单的Quad
for (int x = 0; x <= _grid.Width; x++)
{
CreateLine(
_grid.GridVerticesToWorld(x, 0)[0],
_grid.GridVerticesToWorld(x, _grid.Height)[0],
gridLineWidth,
gridLineColor
);
}
for (int y = 0; y <= _grid.Height; y++)
{
CreateLine(
_grid.GridVerticesToWorld(0, y)[0],
_grid.GridVerticesToWorld(_grid.Width, y)[0],
gridLineWidth,
gridLineColor
);
}
}
/// <summary>
/// 创建一条线
/// </summary>
private void CreateLine(Vector3 start, Vector3 end, float width, Color color)
{
GameObject lineObj = new GameObject("GridLine");
lineObj.transform.SetParent(_gridLinesParent.transform);
lineObj.transform.localPosition = Vector3.zero;
LineRenderer lineRenderer = lineObj.AddComponent<LineRenderer>();
lineRenderer.useWorldSpace = true;
lineRenderer.positionCount = 2;
lineRenderer.SetPosition(0, start);
lineRenderer.SetPosition(1, end);
lineRenderer.startWidth = width;
lineRenderer.endWidth = width;
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
lineRenderer.startColor = color;
lineRenderer.endColor = color;
lineRenderer.sortingOrder = 0;
}
/// <summary>
/// 创建单元格精灵
/// </summary>
private void CreateCellSprites()
{
// 清除旧的单元格
ClearCellSprites();
// 为每个单元格创建可视化对象
for (int x = 0; x < _grid.Width; x++)
{
for (int y = 0; y < _grid.Height; y++)
{
CreateCellSprite(x, y);
}
}
}
/// <summary>
/// 创建单个单元格精灵
/// </summary>
private void CreateCellSprite(int x, int y)
{
GameObject cellObj = new GameObject($"Cell_{x}_{y}");
cellObj.transform.SetParent(_cellsParent.transform);
cellObj.transform.position = _grid.GridToWorld(x, y);
SpriteRenderer spriteRenderer = cellObj.AddComponent<SpriteRenderer>();
// 如果没有指定Sprite,创建一个简单的白色Sprite
if (cellSprite == null)
{
cellSprite = CreateDefaultSprite();
}
spriteRenderer.sprite = cellSprite;
spriteRenderer.color = emptyCellColor;
spriteRenderer.sortingOrder = 1;
// 设置大小
float spriteSize = _grid.CellSize * 0.9f; // 稍微小一点,留出网格线空间
cellObj.transform.localScale = new Vector3(spriteSize, spriteSize, 1f);
// 如果有材质,应用材质
if (cellMaterial != null)
{
spriteRenderer.material = cellMaterial;
}
_cellObjects[(x, y)] = cellObj;
}
/// <summary>
/// 创建默认的白色Sprite
/// </summary>
private Sprite CreateDefaultSprite()
{
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, Color.white);
texture.Apply();
return Sprite.Create(texture, new Rect(0, 0, 1, 1), new Vector2(0.5f, 0.5f), 1f);
}
/// <summary>
/// 更新单元格可视化状态
/// </summary>
public void UpdateCellVisual(int x, int y)
{
if (!_cellObjects.TryGetValue((x, y), out GameObject cellObj))
{
return;
}
SpriteRenderer spriteRenderer = cellObj.GetComponent<SpriteRenderer>();
if (spriteRenderer == null) return;
GridCellState state = _grid.GetCellState(x, y);
spriteRenderer.color = state == GridCellState.Occupied ? occupiedCellColor : emptyCellColor;
}
/// <summary>
/// 更新所有单元格可视化
/// </summary>
public void UpdateAllCellsVisual()
{
if (_grid == null) return;
for (int x = 0; x < _grid.Width; x++)
{
for (int y = 0; y < _grid.Height; y++)
{
UpdateCellVisual(x, y);
}
}
}
/// <summary>
/// 清除单元格精灵
/// </summary>
private void ClearCellSprites()
{
foreach (var kvp in _cellObjects)
{
if (Application.isPlaying)
{
Destroy(kvp.Value);
}
else
{
DestroyImmediate(kvp.Value);
}
}
_cellObjects.Clear();
}
/// <summary>
/// 清除所有可视化
/// </summary>
private void ClearVisualization()
{
ClearCellSprites();
foreach (Transform child in _gridLinesParent.transform)
{
if (Application.isPlaying)
{
Destroy(child.gameObject);
}
else
{
DestroyImmediate(child.gameObject);
}
}
}
private void OnDestroy()
{
ClearVisualization();
}
// 在编辑器中预览网格
private void OnDrawGizmos()
{
if (_grid == null) return;
// 绘制网格边界
Gizmos.color = gridLineColor;
Vector3 bottomLeft = _grid.GridToWorld(0, 0);
Vector3 bottomRight = _grid.GridToWorld(_grid.Width, 0);
Vector3 topLeft = _grid.GridToWorld(0, _grid.Height);
Vector3 topRight = _grid.GridToWorld(_grid.Width, _grid.Height);
Gizmos.DrawLine(bottomLeft, bottomRight);
Gizmos.DrawLine(bottomRight, topRight);
Gizmos.DrawLine(topRight, topLeft);
Gizmos.DrawLine(topLeft, bottomLeft);
}
}
}