using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Mathematics; using Unity.VisualScripting; using UnityEngine; public class TowerPlacementManager : MonoBehaviour { /// /// Sender /// public static event Action OnSpawnGridRequested; public static event Action OnGridDeleteRequested; public static TowerPlacementManager Instance; [Header("Debug")] [SerializeField] private bool RebuildGrid = false; // Section: Mouse private SlotManager CurrentSelectedSlot; private SlotManager CurrentHovered; // Not implemented private int CurrentRotation = 0; // 0, 1, 2, 3 private GameObject SilhouettedObject; // Section: Debug public GameObject DebugTowerPrefab; private void Start() { if (Instance != this) Destroy(Instance); Instance = this; OnSpawnGridRequested?.Invoke(this); } private void Update() { if (Input.GetKeyDown(KeyCode.R) && Input.GetKey(KeyCode.LeftShift)) { CurrentRotation--; CurrentRotation = CurrentRotation % 4; } else if (Input.GetKeyDown(KeyCode.R)) { CurrentRotation++; CurrentRotation = CurrentRotation % 4; } if (RebuildGrid) { RebuildGrid = false; OnGridDeleteRequested?.Invoke(this); OnSpawnGridRequested?.Invoke(this); } } public void OnSlotClicked(SlotManager slot, GridManager grid, int x, int y) { slot.gameObject.GetComponentInChildren().material.color = Color.blue; OnSelectSlot(slot); SpawnTowerAtSelected(DebugTowerPrefab); } // Called when a slot is selected public void OnSelectSlot(SlotManager slot) { // Detects if the selected slot is new if (CurrentSelectedSlot != null && CurrentSelectedSlot != slot) OnDeselectSlot(CurrentSelectedSlot, slot); CurrentSelectedSlot = slot; slot.gameObject.GetComponentInChildren().material.color = Color.blue; } // Called when another slot is getting selected public void OnDeselectSlot(SlotManager prevSlot, SlotManager newSlot) { prevSlot.gameObject.GetComponentInChildren().material.color = Color.white; } public void SpawnTowerAtSelected(GameObject towerPrefab) { var spawnedTower = Instantiate(towerPrefab, CurrentSelectedSlot.transform); Quaternion newRotation = Quaternion.AngleAxis(CurrentRotation * 90f, transform.up); spawnedTower.transform.localRotation = newRotation; } public void OnSlotHovered(SlotManager slot, GridManager grid, int x, int y) { if (SilhouettedObject == null) SilhouettedObject = ToSilhouette(DebugTowerPrefab); // Sets tower rotation Quaternion newRotation = Quaternion.AngleAxis(CurrentRotation * 90f, transform.up); SilhouettedObject.transform.localRotation = newRotation; Vector3 offset = DebugTowerPrefab.transform.position; //SilhouettedObject.SetActive(true); SilhouettedObject.transform.parent = slot.TowerSpawnPoint.transform; SilhouettedObject.transform.localPosition = offset; } public void OnSlotUnHovered(SlotManager slot, GridManager grid, int x, int y) { //SilhouettedObject.SetActive(false); SilhouettedObject.transform.parent = null; SilhouettedObject.transform.position = Vector3.zero; } [Space(10)] public Material SilhouetteMaterial; public GameObject ToSilhouette(GameObject obj) { // if prefab, then spawn it if (obj.scene.name == null) obj = Instantiate(obj); Component[] objScripts = obj.GetComponents(); objScripts = objScripts.Concat(obj.GetComponentsInChildren()).ToArray(); for (int i = 0; i < objScripts.Length; i++) { var comp = objScripts[i]; if (comp is not Renderer && comp is not Transform && comp is not MeshFilter) { Destroy(comp); } else if (typeof(Renderer).IsAssignableFrom(comp)) { var renderer = comp as Renderer; renderer.materials = new Material[] { SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial }; } } return obj; } }