Эффективная смена текстуры блока в зависимости от наличия соседних блоков
У меня есть скрипт на блоках, который в зависимости от положения и расположения рядом стоящих блоков меняет текстуру на нужную, когда ломался или ставился блок рядом, чтобы было плавная картинка в целом. Также есть объект мир со скриптом игровой логики, в котором содержатся все блоки в мире. Вопрос в следующем: лучше оставить как есть, то есть каждый блок сам отслеживает положения рядом стоящих блоков, или лучше в игровой логике проходить циклом по каждому блоку и проверять это положение для каждого? как лучше будет со стороны быстродействия или работоспособности
Ответы (1 шт):
Именование для 2д поле:
- 'Блок' называют
Tile(плитка) илиCell(ячейка) - 'Мир' называют
TileGrid/TileMap/TileBoard.
У тайла должно быть событие изменения, на которое реагируют соседние блоки.
using System;
using System.Collections.Generic;
public class Tile : MonoBehaviour
{
public enum TileSide { Right, Left, Top, Down }
public event Action Changed; // событие
private Tile _right, _left, _top, _down;
public void DoSomething ()
{
// изменения
Changed?.Invoke(); // вызов события изменения
}
public void AddNeighbour (Tile tile, TileSide side)
{
switch (side) {
case TileSide.Right:
_right = tile;
_right.Changed += OnNeighbourChange; // подписка на событие соседа
break;
case TileSide.Left:
_left = tile;
_left.Changed += OnNeighbourChange; // подписка на событие соседа
break;
case TileSide.Top:
_top = tile;
_top.Changed += OnNeighbourChange; // подписка на событие соседа
break;
case TileSide.Down:
_down = tile;
_down.Changed += OnNeighbourChange; // подписка на событие соседа
break;
}
}
private void OnNeighbourChange () // у одного из соседей изменения
{
}
}
public class TileGrid : MonoBehaviour
{
[SerializeField] private Vector2Int _gridSize = new Vector2Int(10, 10);
[SerializeField] private Vector2 _tileSize = new Vector2(32, 32);
[Space]
[SerializeField] private Tile _tileTemplate;
private Tile[,] _grid;
private void Start ()
{
_grid = new Tile[_gridSize.x, _gridSize.y];
for (int x = 0; x < _gridSize.x; x++)
for (int y = 0; y < _gridSize.y; y++)
{
_grid[x, y] = Instantiate(_tileTemplate, transform);
_grid[x, y].transform.localPosition = new Vector3(x*_tileSize.x, y*_tileSize.y, 0);
}
for (int x = 0; x < _gridSize.x-1; x++)
for (int y = 0; y < _gridSize.y-1; y++)
{
SetHorizontalTilePire(_grid[x, y], _grid[x+1, y]);
SetVerticalTilePire(_grid[x, y], _grid[x, y+1]);
}
}
private void SetHorizontalTilePire (Tile left, Tile right)
{
left.SetNeighbour(right, Tile.TileSide.Right);
right.SetNeighbour(left, Tile.TileSide.Left);
}
private void SetVerticalTilePire (Tile down, Tile top)
{
down.AddNeighbour(top, Tile.TileSide.Top);
top.AddNeighbour(down, Tile.TileSide.Down);
}
}