using System; using System.Collections; using System.Collections.Generic; using System.Linq; using CodeMonkey.Utils; using UnityEngine; public class GroundGridControllerScript : MonoBehaviour { public static GroundGridControllerScript Instance { get; private set; } public event EventHandler OnSelectedChanged; public event EventHandler OnObjectPlaced; private GridXZ grid; [SerializeField] List placedObjectTypeSOList; PlacedObjectTypeSO activePlacedObjectTypeSO; [SerializeField] LayerMask mousePlaneLayerMask; PlacedObjectTypeSO.Dir dir = PlacedObjectTypeSO.Dir.Down; int gridWidth = 50; int gridHeight = 50; float cellSize = 10f; private void Awake() { Instance = this; grid = new GridXZ(gridWidth, gridHeight, cellSize, Vector3.zero, (GridXZ g, int x, int y) => new BuildingGridNode(g, x, y)); } internal Quaternion GetPlacedObjectRotation() { if (activePlacedObjectTypeSO != null) { return Quaternion.Euler(0, activePlacedObjectTypeSO.GetRotationAngle(dir), 0); } else { return Quaternion.identity; } } internal Vector2Int GetPlacedObjectRotationOffset() { if (activePlacedObjectTypeSO != null) { return activePlacedObjectTypeSO.GetRotationOffset(dir); } else { return Vector2Int.zero; } } internal PlacedObjectTypeSO GetActiveObjectTypeSO() { return activePlacedObjectTypeSO; } internal Vector3 GetMouseWorldSnappedPosition() { Vector3 mousePosition = GetMousePosition3d(); grid.GetXZ(mousePosition, out int x, out int z); if (activePlacedObjectTypeSO != null) { Vector2Int rotationOffset = activePlacedObjectTypeSO.GetRotationOffset(dir); Vector3 placedObjectWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, 0, rotationOffset.y); return placedObjectWorldPosition; } else { return mousePosition; } } public GridXZ GetGridXZ() { return grid; } private void Update() { if (Input.GetMouseButtonDown(0) && activePlacedObjectTypeSO != null) { grid.GetXZ(GetMousePosition3d(), out int x, out int z); if (x >= 0 && z >= 0) { List gridPositionList = activePlacedObjectTypeSO.GetGridPositionList(new Vector2Int(x, z), dir); if (gridPositionList.TrueForAll(p => ((BuildingGridNode)grid.GetGridObject(p.x, p.y)).CanBuild(activePlacedObjectTypeSO))) { Vector2Int rotationOffset = activePlacedObjectTypeSO.GetRotationOffset(dir); Vector3 placedObejctWorldPosition = grid.GetWorldPosition(x, z) + new Vector3(rotationOffset.x, 0, rotationOffset.y) * grid.GetCellSize(); Transform transform = Instantiate( activePlacedObjectTypeSO.prefab, placedObejctWorldPosition, Quaternion.Euler(0, activePlacedObjectTypeSO.GetRotationAngle(dir), 0)); foreach (Vector2Int gridPosition in gridPositionList) { grid.GetGridObject(gridPosition.x, gridPosition.y).SetTransform(transform); } OnObjectPlaced?.Invoke(this, EventArgs.Empty); } else { UtilsClass.CreateWorldTextPopup("Connot build here!", GetMousePosition3d()); } } } else if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) { DeselectObjectType(); } if (Input.GetKeyDown(KeyCode.R)) { dir = PlacedObjectTypeSO.GetNextDir(dir); } } public void SetActiveObejctToPlace(PlacedObjectTypeSO o) { activePlacedObjectTypeSO = o; OnSelectedChanged?.Invoke(this, EventArgs.Empty); } public Vector3 GetMousePosition3d() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Physics.Raycast(ray, out RaycastHit raycastHit, 999f, mousePlaneLayerMask); return raycastHit.point; } private void DeselectObjectType() { activePlacedObjectTypeSO = null; RefreshSelectedObjectType(); } private void RefreshSelectedObjectType() { OnSelectedChanged?.Invoke(this, EventArgs.Empty); } }