GroundGridControllerScript.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using CodeMonkey.Utils;
  6. using UnityEngine;
  7. public class GroundGridControllerScript : MonoBehaviour {
  8. public static GroundGridControllerScript Instance { get; private set; }
  9. public event EventHandler OnSelectedChanged;
  10. public event EventHandler OnObjectPlaced;
  11. private GridXZ<BuildingGridNode> grid;
  12. [SerializeField] List<PlacedObjectTypeSO> placedObjectTypeSOList;
  13. PlacedObjectTypeSO activePlacedObjectTypeSO;
  14. [SerializeField] LayerMask mousePlaneLayerMask;
  15. PlacedObjectTypeSO.Dir dir = PlacedObjectTypeSO.Dir.Down;
  16. int gridWidth = 50;
  17. int gridHeight = 50;
  18. float cellSize = 10f;
  19. private void Awake() {
  20. Instance = this;
  21. grid = new GridXZ<BuildingGridNode>(gridWidth, gridHeight, cellSize, Vector3.zero, (GridXZ<BuildingGridNode> g, int x, int y) => new BuildingGridNode(g, x, y));
  22. }
  23. internal Quaternion GetPlacedObjectRotation() {
  24. if (activePlacedObjectTypeSO != null) {
  25. return Quaternion.Euler(0, activePlacedObjectTypeSO.GetRotationAngle(dir), 0);
  26. } else {
  27. return Quaternion.identity;
  28. }
  29. }
  30. internal Vector2Int GetPlacedObjectRotationOffset() {
  31. if (activePlacedObjectTypeSO != null) {
  32. return activePlacedObjectTypeSO.GetRotationOffset(dir);
  33. } else {
  34. return Vector2Int.zero;
  35. }
  36. }
  37. internal PlacedObjectTypeSO GetActiveObjectTypeSO() {
  38. return activePlacedObjectTypeSO;
  39. }
  40. internal Vector3 GetMouseWorldSnappedPosition() {
  41. Vector3 mousePosition = GetMousePosition3d();
  42. grid.GetXZ(mousePosition, out int x, out int z);
  43. if (activePlacedObjectTypeSO != null) {
  44. Vector2Int rotationOffset = activePlacedObjectTypeSO.GetRotationOffset(dir);
  45. Vector3 placedObjectWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, 0, rotationOffset.y);
  46. return placedObjectWorldPosition;
  47. } else {
  48. return mousePosition;
  49. }
  50. }
  51. public GridXZ<BuildingGridNode> GetGridXZ() {
  52. return grid;
  53. }
  54. private void Update() {
  55. if (Input.GetMouseButtonDown(0) && activePlacedObjectTypeSO != null) {
  56. grid.GetXZ(GetMousePosition3d(), out int x, out int z);
  57. if (x >= 0 && z >= 0) {
  58. List<Vector2Int> gridPositionList = activePlacedObjectTypeSO.GetGridPositionList(new Vector2Int(x, z), dir);
  59. if (gridPositionList.TrueForAll(p => ((BuildingGridNode)grid.GetGridObject(p.x, p.y)).CanBuild(activePlacedObjectTypeSO))) {
  60. Vector2Int rotationOffset = activePlacedObjectTypeSO.GetRotationOffset(dir);
  61. Vector3 placedObejctWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, 0, rotationOffset.y) * grid.GetCellSize();
  62. Transform transform = Instantiate(
  63. activePlacedObjectTypeSO.prefab,
  64. placedObejctWorldPosition,
  65. Quaternion.Euler(0, activePlacedObjectTypeSO.GetRotationAngle(dir), 0));
  66. foreach (Vector2Int gridPosition in gridPositionList) {
  67. grid.GetGridObject(gridPosition.x, gridPosition.y).SetTransform(transform);
  68. }
  69. OnObjectPlaced?.Invoke(this, EventArgs.Empty);
  70. } else {
  71. UtilsClass.CreateWorldTextPopup("Connot build here!", GetMousePosition3d());
  72. }
  73. }
  74. } else if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) {
  75. DeselectObjectType();
  76. }
  77. if (Input.GetKeyDown(KeyCode.R)) {
  78. dir = PlacedObjectTypeSO.GetNextDir(dir);
  79. }
  80. }
  81. public void SetActiveObejctToPlace(PlacedObjectTypeSO o) {
  82. activePlacedObjectTypeSO = o;
  83. OnSelectedChanged?.Invoke(this, EventArgs.Empty);
  84. }
  85. public Vector3 GetMousePosition3d() {
  86. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  87. Physics.Raycast(ray, out RaycastHit raycastHit, 999f, mousePlaneLayerMask);
  88. return raycastHit.point;
  89. }
  90. private void DeselectObjectType() {
  91. activePlacedObjectTypeSO = null;
  92. RefreshSelectedObjectType();
  93. }
  94. private void RefreshSelectedObjectType() {
  95. OnSelectedChanged?.Invoke(this, EventArgs.Empty);
  96. }
  97. }