147 lines
5.4 KiB
C#

using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
public class BoardFitter : MonoBehaviour
{
[Header("Рамка")]
[SerializeField] private SpriteRenderer _innerLineRenderer;
[SerializeField] private SpriteRenderer _outlineRenderer;
[SerializeField] private Vector2 _innerLinePadding = new(0.64f, 0.69f);
[Header("Задний фон")]
[SerializeField, FormerlySerializedAs("backgroundRenderer")] private SpriteRenderer _backgroundRenderer;
[SerializeField, FormerlySerializedAs("bgHorizontalPadding")] private float _backgroundHorizontalPadding = 0.78f;
[SerializeField, FormerlySerializedAs("bgVerticalPadding")] private float _backgroundVerticalPadding = 0.68f;
[Header("Ячейки")]
[SerializeField, FormerlySerializedAs("cellPrefab")] private GameObject _cellPrefab;
[SerializeField, FormerlySerializedAs("cellsRoot")] private Transform _cellsRoot;
[SerializeField, FormerlySerializedAs("cellScale")] private float _cellScale = 1f;
[SerializeField, FormerlySerializedAs("cellOffset")] private float _cellOffset = 0.1f;
[SerializeField, FormerlySerializedAs("cellGroupPadding")] private float _cellGroupPadding = 3f;
[Header("Подготовленная позиция")]
[SerializeField, FormerlySerializedAs("stickedOffset")] private float _stickedOffset = 2f;
private List<GameObject> _cells;
private Color _currentCellsColor = Color.white;
private bool _hasCurrentCellsColor;
public BoardConfiguration GetConfiguration()
{
if (_cells == null)
throw new System.NullReferenceException($"Объект не инициализирован {this}");
Vector2 offset = new(_cellScale + _cellOffset, -(_cellScale + _cellOffset));
return new BoardConfiguration(
topLeft: _cells[0].transform,
cellOffset: offset,
stickedYOffset: _stickedOffset);
}
public void FitBoard(int columns, int rows)
{
columns = Mathf.Clamp(columns, 4, 8);
rows = Mathf.Clamp(rows, 4, 8);
ClearCells();
GenerateCells(columns, rows);
float groupWidth = (_cellScale + _cellOffset) * columns;
float groupHeight = (_cellScale + _cellOffset) * rows;
FitFrame(groupWidth, groupHeight);
FitCellsRoot(groupWidth, groupHeight);
}
public Sequence GetColorSequence(Color innerColor, Color outlineColor, Color cellsColor, float duration)
{
_currentCellsColor = cellsColor;
_hasCurrentCellsColor = true;
Sequence sequence = DOTween.Sequence();
sequence.Join(_innerLineRenderer.DOColor(innerColor, duration));
sequence.Join(_outlineRenderer.DOColor(outlineColor, duration));
foreach (SpriteRenderer cellRenderer in _cellsRoot.GetComponentsInChildren<SpriteRenderer>(true))
sequence.Join(cellRenderer.DOColor(cellsColor, duration));
return sequence;
}
public void SetColorsImmediately(Color innerColor, Color outlineColor, Color cellsColor)
{
_currentCellsColor = cellsColor;
_hasCurrentCellsColor = true;
_innerLineRenderer.DOKill();
_outlineRenderer.DOKill();
_innerLineRenderer.color = innerColor;
_outlineRenderer.color = outlineColor;
foreach (SpriteRenderer cellRenderer in _cellsRoot.GetComponentsInChildren<SpriteRenderer>(true))
{
cellRenderer.DOKill();
cellRenderer.color = cellsColor;
}
}
private void FitCellsRoot(float groupWidth, float groupHeight)
{
float rootX = -groupWidth * 0.5f;
float rootY = (groupHeight + _outlineRenderer.size.y - _cellScale) * 0.5f;
_cellsRoot.localPosition = new Vector3(rootX, rootY, 0f);
}
private void FitFrame(float groupWidth, float groupHeight)
{
Vector2 frameSize = new(groupWidth + _cellGroupPadding, groupHeight + _cellGroupPadding);
_outlineRenderer.size = frameSize;
_innerLineRenderer.size = new Vector2(
Mathf.Max(frameSize.x - _innerLinePadding.x, 0f),
Mathf.Max(frameSize.y - _innerLinePadding.y, 0f));
_backgroundRenderer.transform.localScale = new Vector3(
frameSize.x - _backgroundHorizontalPadding,
frameSize.y - _backgroundVerticalPadding,
1f);
}
private void GenerateCells(int columns, int rows)
{
_cells = new List<GameObject>();
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
GameObject cellObject = Instantiate(_cellPrefab, _cellsRoot);
Transform cell = cellObject.transform;
cell.localScale = new Vector3(_cellScale, _cellScale, 1f);
float x = column * (_cellScale + _cellOffset) + _cellScale * 0.5f;
float y = -row * (_cellScale + _cellOffset) - _cellScale * 0.5f;
cell.localPosition = new Vector3(x, y, 0f);
if (_hasCurrentCellsColor)
{
foreach (SpriteRenderer cellRenderer in cellObject.GetComponentsInChildren<SpriteRenderer>(true))
cellRenderer.color = _currentCellsColor;
}
_cells.Add(cellObject);
}
}
}
private void ClearCells()
{
for (int i = _cellsRoot.childCount - 1; i >= 0; i--)
Destroy(_cellsRoot.GetChild(i).gameObject);
}
}