using System; using System.Collections.Generic; using System.Linq; using Actions; using UnityEngine; using UnityEngine.Serialization; namespace Grid { public class GridSystemVisual : MonoBehaviour { public enum GridVisualType { White, Red, Blue, Yellow, RedSoft } [FormerlySerializedAs("GridSystemVisualSinglePrefab")] [SerializeField] private Transform gridSystemVisualSinglePrefab; [FormerlySerializedAs("gridVisualTypeMaterials")] [SerializeField] private List gridVisualTypeMaterialList; private GridSystemVisualSingle[,,] gridSystemVisualSingleArray; private static GridSystemVisual Instance { get; set; } private void Awake() { if (Instance is not null) { Debug.LogError($"There is more than one GridSystemVisual! {transform} - {Instance}"); Destroy(gameObject); return; } Instance = this; } private void Start() { int width = LevelGrid.Instance.GetWidth(); int height = LevelGrid.Instance.GetHeight(); int floorAmount = LevelGrid.Instance.FloorAmount; gridSystemVisualSingleArray = new GridSystemVisualSingle[width, height, floorAmount]; for (int xPosition = 0; xPosition < width; xPosition++) { for (int zPosition = 0; zPosition < height; zPosition++) { for (int floor = 0; floor < floorAmount; floor++) { Transform gridSystemVisualSingleTransform = Instantiate(gridSystemVisualSinglePrefab, LevelGrid.Instance.GetWorldPosition(new(xPosition, zPosition, floor)), Quaternion.identity); gridSystemVisualSingleArray[xPosition, zPosition, floor] = gridSystemVisualSingleTransform.GetComponent(); } } } UnitActionSystem.Instance.OnSelectedActionChanged += UnitActionSystem_OnSelectedActionChanged; UnitActionSystem.Instance.OnBusyChanged += UnitActionSystem_OnOnBusyChanged; // LevelGrid.Instance.OnAnyUnitMovedGridPosition += LevelGrid_OnAnyUnitMovedGridPosition; UpdateGridVisual(); } private void UnitActionSystem_OnOnBusyChanged(object sender, bool e) => UpdateGridVisual(); // private void LevelGrid_OnAnyUnitMovedGridPosition(object sender, EventArgs e) => UpdateGridVisual(); private void UnitActionSystem_OnSelectedActionChanged(object sender, EventArgs e) => UpdateGridVisual(); private void HideAllGridPosition() { foreach (GridSystemVisualSingle gridSystemVisualSingle in gridSystemVisualSingleArray) gridSystemVisualSingle.Hide(); } private void ShowGridPositionList(List gridPositionList, GridVisualType gridVisualType) { foreach (GridPosition gridPosition in gridPositionList) gridSystemVisualSingleArray[gridPosition.XPosition, gridPosition.ZPosition, gridPosition.Floor].Show(GetGridVisualTypeMaterial(gridVisualType)); } private void ShowGridPositionRange(GridPosition gridPosition, int range, GridVisualType gridVisualType) { List gridPositionList = new(); for (int xPosition = -range; xPosition <= range; xPosition++) { for (int zPosition = -range; zPosition <= range; zPosition++) { GridPosition testGridPosition = gridPosition + new GridPosition(xPosition, zPosition, 0); if (!LevelGrid.Instance.IsValidGridPosition(testGridPosition)) continue; //Only return valid grid positions if (Mathf.Abs(xPosition) + Mathf.Abs(zPosition) > range) continue; //Out of Range gridPositionList.Add(testGridPosition); } } ShowGridPositionList(gridPositionList, gridVisualType); } private void ShowGridPositionRangeSquare(GridPosition gridPosition, int range, GridVisualType gridVisualType) { List gridPositionList = new(); for (int xPosition = -range; xPosition <= range; xPosition++) { for (int zPosition = -range; zPosition <= range; zPosition++) { GridPosition testGridPosition = gridPosition + new GridPosition(xPosition, zPosition, 0); if (!LevelGrid.Instance.IsValidGridPosition(testGridPosition)) continue; //Only return valid grid positions gridPositionList.Add(testGridPosition); } } ShowGridPositionList(gridPositionList, gridVisualType); } private void UpdateGridVisual() { HideAllGridPosition(); BaseAction selectedAction = UnitActionSystem.Instance.SelectedAction; Unit selectedUnit = UnitActionSystem.Instance.SelectedUnit; GridVisualType gridVisualType; switch (selectedAction) { case SpinAction: gridVisualType = GridVisualType.Blue; break; case GrenadeAction: gridVisualType = GridVisualType.Yellow; break; case ShootAction: gridVisualType = GridVisualType.Red; ShowGridPositionRange(selectedUnit.GridPosition, selectedUnit.GetAction().MaxShootDistance, GridVisualType.RedSoft); break; case SwordAction: gridVisualType = GridVisualType.Red; ShowGridPositionRangeSquare(selectedUnit.GridPosition, selectedUnit.GetAction().MaxSwordDistance, GridVisualType.RedSoft); break; case InteractAction: gridVisualType = GridVisualType.Blue; break; default: gridVisualType = GridVisualType.White; break; } ShowGridPositionList(selectedAction.GetValidActionGridPositionList(), gridVisualType); } private Material GetGridVisualTypeMaterial(GridVisualType gridVisualType) { return (from gridVisualTypeMaterial in gridVisualTypeMaterialList where gridVisualTypeMaterial.gridVisualType == gridVisualType select gridVisualTypeMaterial.material).FirstOrDefault(); } [Serializable] public struct GridVisualTypeMaterial { public GridVisualType gridVisualType; public Material material; } } }