GridBuildingSystem2D.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using CodeMonkey.Utils;
  6. public class GridBuildingSystem2D : MonoBehaviour {
  7. public static GridBuildingSystem2D Instance { get; private set; }
  8. public event EventHandler OnSelectedChanged;
  9. public event EventHandler OnObjectPlaced;
  10. private Grid<GridObject> grid;
  11. [SerializeField] private List<PlacedObjectTypeSO> placedObjectTypeSOList = null;
  12. private PlacedObjectTypeSO placedObjectTypeSO;
  13. private PlacedObjectTypeSO.Dir dir;
  14. private void Awake() {
  15. Instance = this;
  16. int gridWidth = 10;
  17. int gridHeight = 10;
  18. float cellSize = 10f;
  19. grid = new Grid<GridObject>(gridWidth, gridHeight, cellSize, new Vector3(0, 0, 0), (Grid<GridObject> g, int x, int y) => new GridObject(g, x, y));
  20. placedObjectTypeSO = null;
  21. }
  22. public class GridObject {
  23. private Grid<GridObject> grid;
  24. private int x;
  25. private int y;
  26. public PlacedObject_Done placedObject;
  27. public GridObject(Grid<GridObject> grid, int x, int y) {
  28. this.grid = grid;
  29. this.x = x;
  30. this.y = y;
  31. placedObject = null;
  32. }
  33. public override string ToString() {
  34. return x + ", " + y + "\n" + placedObject;
  35. }
  36. public void SetPlacedObject(PlacedObject_Done placedObject) {
  37. this.placedObject = placedObject;
  38. grid.TriggerGridObjectChanged(x, y);
  39. }
  40. public void ClearPlacedObject() {
  41. placedObject = null;
  42. grid.TriggerGridObjectChanged(x, y);
  43. }
  44. public PlacedObject_Done GetPlacedObject() {
  45. return placedObject;
  46. }
  47. public bool CanBuild() {
  48. return placedObject == null;
  49. }
  50. }
  51. private void Update() {
  52. if (Input.GetMouseButtonDown(0) && placedObjectTypeSO != null) {
  53. Vector3 mousePosition = UtilsClass.GetMouseWorldPosition();
  54. grid.GetXY(mousePosition, out int x, out int z);
  55. Vector2Int placedObjectOrigin = new Vector2Int(x, z);
  56. // Test Can Build
  57. List<Vector2Int> gridPositionList = placedObjectTypeSO.GetGridPositionList(placedObjectOrigin, dir);
  58. bool canBuild = true;
  59. foreach (Vector2Int gridPosition in gridPositionList) {
  60. if (!grid.GetGridObject(gridPosition.x, gridPosition.y).CanBuild()) {
  61. canBuild = false;
  62. break;
  63. }
  64. }
  65. if (canBuild) {
  66. Vector2Int rotationOffset = placedObjectTypeSO.GetRotationOffset(dir);
  67. Vector3 placedObjectWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, rotationOffset.y) * grid.GetCellSize();
  68. PlacedObject_Done placedObject = PlacedObject_Done.Create(placedObjectWorldPosition, placedObjectOrigin, dir, placedObjectTypeSO);
  69. placedObject.transform.rotation = Quaternion.Euler(0, 0, -placedObjectTypeSO.GetRotationAngle(dir));
  70. foreach (Vector2Int gridPosition in gridPositionList) {
  71. grid.GetGridObject(gridPosition.x, gridPosition.y).SetPlacedObject(placedObject);
  72. }
  73. OnObjectPlaced?.Invoke(this, EventArgs.Empty);
  74. //DeselectObjectType();
  75. } else {
  76. // Cannot build here
  77. UtilsClass.CreateWorldTextPopup("Cannot Build Here!", mousePosition);
  78. }
  79. }
  80. if (Input.GetKeyDown(KeyCode.R)) {
  81. dir = PlacedObjectTypeSO.GetNextDir(dir);
  82. }
  83. if (Input.GetKeyDown(KeyCode.Alpha1)) { placedObjectTypeSO = placedObjectTypeSOList[0]; RefreshSelectedObjectType(); }
  84. if (Input.GetKeyDown(KeyCode.Alpha2)) { placedObjectTypeSO = placedObjectTypeSOList[1]; RefreshSelectedObjectType(); }
  85. if (Input.GetKeyDown(KeyCode.Alpha3)) { placedObjectTypeSO = placedObjectTypeSOList[2]; RefreshSelectedObjectType(); }
  86. if (Input.GetKeyDown(KeyCode.Alpha4)) { placedObjectTypeSO = placedObjectTypeSOList[3]; RefreshSelectedObjectType(); }
  87. if (Input.GetKeyDown(KeyCode.Alpha5)) { placedObjectTypeSO = placedObjectTypeSOList[4]; RefreshSelectedObjectType(); }
  88. if (Input.GetKeyDown(KeyCode.Alpha6)) { placedObjectTypeSO = placedObjectTypeSOList[5]; RefreshSelectedObjectType(); }
  89. if (Input.GetKeyDown(KeyCode.Alpha0)) { DeselectObjectType(); }
  90. if (Input.GetMouseButtonDown(1)) {
  91. Vector3 mousePosition = UtilsClass.GetMouseWorldPosition();
  92. PlacedObject_Done placedObject = grid.GetGridObject(mousePosition).GetPlacedObject();
  93. if (placedObject != null) {
  94. // Demolish
  95. placedObject.DestroySelf();
  96. List<Vector2Int> gridPositionList = placedObject.GetGridPositionList();
  97. foreach (Vector2Int gridPosition in gridPositionList) {
  98. grid.GetGridObject(gridPosition.x, gridPosition.y).ClearPlacedObject();
  99. }
  100. }
  101. }
  102. }
  103. private void DeselectObjectType() {
  104. placedObjectTypeSO = null; RefreshSelectedObjectType();
  105. }
  106. private void RefreshSelectedObjectType() {
  107. OnSelectedChanged?.Invoke(this, EventArgs.Empty);
  108. }
  109. public Vector2Int GetGridPosition(Vector3 worldPosition) {
  110. grid.GetXY(worldPosition, out int x, out int z);
  111. return new Vector2Int(x, z);
  112. }
  113. public Vector3 GetMouseWorldSnappedPosition() {
  114. Vector3 mousePosition = UtilsClass.GetMouseWorldPosition();
  115. grid.GetXY(mousePosition, out int x, out int y);
  116. if (placedObjectTypeSO != null) {
  117. Vector2Int rotationOffset = placedObjectTypeSO.GetRotationOffset(dir);
  118. Vector3 placedObjectWorldPosition = grid.GetWorldPosition(x, y) + new Vector3(rotationOffset.x, rotationOffset.y) * grid.GetCellSize();
  119. return placedObjectWorldPosition;
  120. } else {
  121. return mousePosition;
  122. }
  123. }
  124. public Quaternion GetPlacedObjectRotation() {
  125. if (placedObjectTypeSO != null) {
  126. return Quaternion.Euler(0, 0, -placedObjectTypeSO.GetRotationAngle(dir));
  127. } else {
  128. return Quaternion.identity;
  129. }
  130. }
  131. public PlacedObjectTypeSO GetPlacedObjectTypeSO() {
  132. return placedObjectTypeSO;
  133. }
  134. }