CMGridBuildingSystem3D.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using CodeMonkey.Utils;
  5. using UnityEngine;
  6. public class CMGridBuildingSystem3D : MonoBehaviour {
  7. public static CMGridBuildingSystem3D Instance { get; private set; }
  8. public event EventHandler OnSelectedChanged;
  9. public event EventHandler OnObjectPlaced;
  10. private GridXZ<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 GridXZ<GridObject>(gridWidth, gridHeight, cellSize, new Vector3(0, 0, 0), (GridXZ<GridObject> g, int x, int y) => new GridObject(g, x, y));
  20. placedObjectTypeSO = null;// placedObjectTypeSOList[0];
  21. }
  22. public class GridObject {
  23. private GridXZ<GridObject> grid;
  24. private int x;
  25. private int y;
  26. public PlacedObject_Done placedObject;
  27. public GridObject(GridXZ<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 = Mouse3D.GetMouseWorldPosition();
  54. grid.GetXZ(mousePosition, out int x, out int z);
  55. Vector2Int placedObjectOrigin = new Vector2Int(x, z);
  56. // placedObjectOrigin = grid.ValidateGridPosition(placedObjectOrigin);
  57. // Test Can Build
  58. List<Vector2Int> gridPositionList = placedObjectTypeSO.GetGridPositionList(placedObjectOrigin, dir);
  59. bool canBuild = true;
  60. foreach (Vector2Int gridPosition in gridPositionList) {
  61. if (!grid.GetGridObject(gridPosition.x, gridPosition.y).CanBuild()) {
  62. canBuild = false;
  63. break;
  64. }
  65. }
  66. if (canBuild) {
  67. Vector2Int rotationOffset = placedObjectTypeSO.GetRotationOffset(dir);
  68. Vector3 placedObjectWorldPosition = grid.GetWorldPosition(placedObjectOrigin.x, placedObjectOrigin.y) + new Vector3(rotationOffset.x, 0, rotationOffset.y) * grid.GetCellSize();
  69. PlacedObject_Done placedObject = PlacedObject_Done.Create(placedObjectWorldPosition, placedObjectOrigin, dir, placedObjectTypeSO);
  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 = Mouse3D.GetMouseWorldPosition();
  92. if (grid.GetGridObject(mousePosition) != null) {
  93. // Valid Grid Position
  94. PlacedObject_Done placedObject = grid.GetGridObject(mousePosition).GetPlacedObject();
  95. if (placedObject != null) {
  96. // Demolish
  97. placedObject.DestroySelf();
  98. List<Vector2Int> gridPositionList = placedObject.GetGridPositionList();
  99. foreach (Vector2Int gridPosition in gridPositionList) {
  100. grid.GetGridObject(gridPosition.x, gridPosition.y).ClearPlacedObject();
  101. }
  102. }
  103. }
  104. }
  105. }
  106. private void DeselectObjectType() {
  107. placedObjectTypeSO = null; RefreshSelectedObjectType();
  108. }
  109. private void RefreshSelectedObjectType() {
  110. OnSelectedChanged?.Invoke(this, EventArgs.Empty);
  111. }
  112. public Vector2Int GetGridPosition(Vector3 worldPosition) {
  113. grid.GetXZ(worldPosition, out int x, out int z);
  114. return new Vector2Int(x, z);
  115. }
  116. public Vector3 GetMouseWorldSnappedPosition() {
  117. Vector3 mousePosition = Mouse3D.GetMouseWorldPosition();
  118. grid.GetXZ(mousePosition, out int x, out int z);
  119. if (placedObjectTypeSO != null) {
  120. Vector2Int rotationOffset = placedObjectTypeSO.GetRotationOffset(dir);
  121. Vector3 placedObjectWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, 0, rotationOffset.y) * grid.GetCellSize();
  122. return placedObjectWorldPosition;
  123. } else {
  124. return mousePosition;
  125. }
  126. }
  127. public Quaternion GetPlacedObjectRotation() {
  128. if (placedObjectTypeSO != null) {
  129. return Quaternion.Euler(0, placedObjectTypeSO.GetRotationAngle(dir), 0);
  130. } else {
  131. return Quaternion.identity;
  132. }
  133. }
  134. public PlacedObjectTypeSO GetPlacedObjectTypeSO() {
  135. return placedObjectTypeSO;
  136. }
  137. }