Skip to content

Instantly share code, notes, and snippets.

@MarGamaDev
Created October 6, 2023 08:58
Show Gist options
  • Save MarGamaDev/109dfd01acba6a90b7f2c7bad63ed2b6 to your computer and use it in GitHub Desktop.
Save MarGamaDev/109dfd01acba6a90b7f2c7bad63ed2b6 to your computer and use it in GitHub Desktop.
using MyBox;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
public class GridManager : MonoBehaviour
{
[SerializeField] private int _gridSize = 3;
[SerializeField] private float _gridSpacing = 6.5f;
[SerializeField] private float _timeToMove = 0.5f;
private List<GridCell> _cells = new List<GridCell>();
private GridCell[,] _grid = new GridCell[3, 3];
private LockableBody[] _lockableBodies;
private SoundPlayer _soundPlayer;
public static GridManager Current
{
get
{
if (!_current)
_current = FindObjectOfType<GridManager>();
return _current;
}
}
private static GridManager _current;
private void Awake()
{
_current = this;
GridCell.TimeToMove = _timeToMove;
_soundPlayer = GetComponent<SoundPlayer>();
}
public void SetGridCells(List<GridCell> roomList)
{
_cells = roomList;
SortCellsToGrid();
}
private void SortCellsToGrid()
{
foreach (GridCell cell in _cells)
{
_grid[cell.CellId.x, cell.CellId.y] = cell;
}
}
/// <summary>
/// Move a column in the grid up or down.
/// </summary>
/// <param name="column"> The index of the column you want to move. </param>
/// <param name="direction"> The direction in which you want to move the column, 1 is up and -1 is down. </param>
public void MoveColumn(int column, int direction)
{
//make list of cells that move
List<GridCell> cellsToMove = new List<GridCell>();
for (int i = 0; i < _gridSize; i++)
{
cellsToMove.Add(_grid[column, i]);
}
if (!cellsToMove.TrueForAll(x => x.IsAllowedToMove))
return;
//copy the cell that goes offscreen
GridCell cellToCopy = direction > 0 ? _grid[column, 2] : _grid[column, 0];
GameObject dummyCellObject = GameObject.Instantiate(cellToCopy.gameObject, cellToCopy.transform.position, cellToCopy.transform.rotation);
GridCell dummyCell = dummyCellObject.GetComponent<GridCell>();
//transport original off of grid
cellToCopy.transform.SetZ(cellToCopy.transform.position.z - (_gridSpacing * _gridSize * direction));
MoveGroup(cellsToMove, dummyCell, new int2(0, direction));
}
/// <summary>
/// Move a row in the grid left or right
/// </summary>
/// <param name="row"> The index of the row you want to move. </param>
/// <param name="direction"> The direction in which you want to move the column, 1 is right, -1 is down. </param>
public void MoveRow(int row, int direction)
{
//make list of cells that move
List<GridCell> cellsToMove = new List<GridCell>();
for (int i = 0; i < _gridSize; i++)
{
cellsToMove.Add(_grid[i, row]);
}
if (!cellsToMove.TrueForAll(x => x.IsAllowedToMove))
return;
//copy the cell that goes offscreen
GridCell cellToCopy = direction > 0 ? _grid[2, row] : _grid[0, row];
GameObject dummyCellObject = GameObject.Instantiate(cellToCopy.gameObject, cellToCopy.transform.position, cellToCopy.transform.rotation);
GridCell dummyCell = dummyCellObject.GetComponent<GridCell>();
//transport original off of grid
cellToCopy.transform.SetX(cellToCopy.transform.position.x - (_gridSpacing * _gridSize * direction));
MoveGroup(cellsToMove, dummyCell, new int2(direction, 0));
}
/// <summary>
/// Move a group of cells and a fake cell in a direction.
/// </summary>
/// <param name="cellsToMove"> The real cells you want to move. </param>
/// <param name="dummyCell"> The fake copy you want to move. </param>
/// <param name="direction"> The direction in which you want to move the cells. </param>
private void MoveGroup(List<GridCell> cellsToMove, GridCell dummyCell, int2 direction)
{
//move all cells and update IDs
float3 displacement = new float3(direction.x * _gridSpacing, 0, direction.y * _gridSpacing);
foreach (GridCell cell in cellsToMove)
{
cell.MoveCell(displacement);
//shift cellIDs with direction, and clamps them within array
int newX = ((cell.CellId.x + direction.x) % _gridSize);
newX = newX < 0 ? _gridSize - 1 : newX;
int newY = ((cell.CellId.y + direction.y) % _gridSize);
newY = newY < 0 ? _gridSize - 1 : newY;
cell.CellId = new int2(newX, newY);
}
dummyCell.MoveCell(displacement, true);
_soundPlayer.Play();
//update array to new positions
SortCellsToGrid();
}
public void LockPhysicsObjects()
{
// Find and loop through all lockable bodies
_lockableBodies = FindObjectsOfType<LockableBody>();
foreach (LockableBody lockableBody in _lockableBodies)
{
// Get bounds off the collider
Bounds objectBounds = lockableBody.GetComponent<Collider>().bounds;
// Get all the cells that the boundingBox intercets
List<GridCell> CollidingCell = new List<GridCell>(_cells.Count);
foreach (GridCell cell in _cells)
{
if (cell.BoundingBox.Intersects(objectBounds))
{
CollidingCell.Add(cell);
}
}
// This should not happen, dont do anything if it does
if (CollidingCell.Count == 0)
Debug.LogError($"{lockableBody.gameObject} not found in any bounding box");
// Set the parent and prepare for move
else if (CollidingCell.Count == 1)
{
GridCell cell = CollidingCell[0];
if (lockableBody.ForceLockCell)
cell.IsLocked = true;
else
lockableBody.transform.SetParent(cell.transform);
}
// Lock all the cells so that boxes in between doors cant move
else
{
foreach (GridCell cell in CollidingCell)
{
cell.IsLocked = true;
}
}
}
}
public void UnlockPhysicsObjects()
{
//reset all lockable bodies
foreach (LockableBody lockableBody in _lockableBodies)
{
if (lockableBody)
lockableBody.transform.SetParent(null);
}
//unlock all cells
foreach (GridCell cell in _cells)
{
cell.IsLocked = false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment