3DTD/Assets/Scripts/PlacementSystem/PlacementManager.cs

180 lines
5.2 KiB
C#
Raw Normal View History

2024-04-20 01:51:12 +02:00
using System;
using System.Collections;
using System.Collections.Generic;
2024-04-20 17:13:17 +02:00
using System.Linq;
2024-04-20 19:22:54 +02:00
using Unity.Mathematics;
2024-04-20 01:51:12 +02:00
using Unity.VisualScripting;
using UnityEngine;
2024-04-21 03:21:23 +02:00
using UnityEngine.EventSystems;
using UnityEngine.UI;
2024-04-20 01:51:12 +02:00
public class TowerPlacementManager : MonoBehaviour
{
2024-04-21 01:43:22 +02:00
public static TowerPlacementManager Instance;
// Spawning grid events
2024-04-20 01:51:12 +02:00
public static event Action<TowerPlacementManager> OnSpawnGridRequested;
2024-04-21 00:39:24 +02:00
public static event Action<TowerPlacementManager> OnGridDeleteRequested;
2024-04-21 01:43:22 +02:00
// Placing tower
public static event Action<TowerInfo> OnTowerPlaced;
2024-04-20 01:51:12 +02:00
2024-04-21 00:39:24 +02:00
[Header("Debug")]
[SerializeField] private bool RebuildGrid = false;
2024-04-20 19:22:54 +02:00
// Section: Mouse
private SlotManager CurrentSelectedSlot;
2024-04-20 20:12:06 +02:00
private int CurrentRotation = 0; // 0, 1, 2, 3
2024-04-20 19:22:54 +02:00
private GameObject SilhouettedObject;
2024-04-21 01:43:22 +02:00
private TowerInfo SelectedTowerInfo;
2024-04-20 15:38:21 +02:00
2024-04-21 01:43:22 +02:00
private GameObject SelectedTowerPrefab => SelectedTowerInfo.prefab;
2024-04-20 16:27:58 +02:00
2024-04-20 01:51:12 +02:00
private void Start()
{
2024-04-20 22:05:01 +02:00
if (Instance != this)
Destroy(Instance);
Instance = this;
2024-04-20 01:51:12 +02:00
OnSpawnGridRequested?.Invoke(this);
}
2024-04-20 20:12:06 +02:00
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;
}
2024-04-21 00:39:24 +02:00
if (RebuildGrid)
{
RebuildGrid = false;
OnGridDeleteRequested?.Invoke(this);
OnSpawnGridRequested?.Invoke(this);
}
2024-04-20 20:12:06 +02:00
}
2024-04-21 01:43:22 +02:00
private void OnEnable()
{
2024-04-21 03:49:10 +02:00
OnTowerPlaced += PlayPlaceSfx;
2024-04-21 01:43:22 +02:00
MoneyManager.OnShopSelected += OnShopSelected;
}
private void OnDisable()
{
2024-04-21 03:49:10 +02:00
OnTowerPlaced -= PlayPlaceSfx;
2024-04-21 01:43:22 +02:00
MoneyManager.OnShopSelected -= OnShopSelected;
}
2024-04-21 03:49:10 +02:00
private void PlayPlaceSfx(TowerInfo info)
{
AudioManager.PlaySound("BuildTower", Vector3.zero);
}
2024-04-21 01:43:22 +02:00
private void OnShopSelected(TowerInfo info)
{
SelectedTowerInfo = info;
2024-04-21 02:16:52 +02:00
Destroy(SilhouettedObject);
2024-04-21 01:43:22 +02:00
}
2024-04-20 01:51:12 +02:00
public void OnSlotClicked(SlotManager slot, GridManager grid, int x, int y)
{
2024-04-20 15:38:21 +02:00
slot.gameObject.GetComponentInChildren<Renderer>().material.color = Color.blue;
OnSelectSlot(slot);
2024-04-20 16:27:58 +02:00
2024-04-21 01:43:22 +02:00
SpawnTowerAtSelected(SelectedTowerPrefab);
2024-04-20 15:38:21 +02:00
}
// Called when a slot is selected
public void OnSelectSlot(SlotManager slot)
{
// Detects if the selected slot is new
2024-04-20 19:22:54 +02:00
if (CurrentSelectedSlot != null && CurrentSelectedSlot != slot)
OnDeselectSlot(CurrentSelectedSlot, slot);
CurrentSelectedSlot = slot;
2024-04-20 15:38:21 +02:00
slot.gameObject.GetComponentInChildren<Renderer>().material.color = Color.blue;
}
2024-04-20 01:51:12 +02:00
2024-04-20 15:38:21 +02:00
// Called when another slot is getting selected
public void OnDeselectSlot(SlotManager prevSlot, SlotManager newSlot)
{
prevSlot.gameObject.GetComponentInChildren<Renderer>().material.color = Color.white;
2024-04-20 01:51:12 +02:00
}
2024-04-20 16:27:58 +02:00
public void SpawnTowerAtSelected(GameObject towerPrefab)
{
2024-04-20 20:12:06 +02:00
var spawnedTower = Instantiate(towerPrefab, CurrentSelectedSlot.transform);
Quaternion newRotation = Quaternion.AngleAxis(CurrentRotation * 90f, transform.up);
spawnedTower.transform.localRotation = newRotation;
2024-04-21 02:25:19 +02:00
2024-04-21 03:07:29 +02:00
FinishBuild();
2024-04-20 19:22:54 +02:00
}
public void OnSlotHovered(SlotManager slot, GridManager grid, int x, int y)
{
if (SilhouettedObject == null)
2024-04-21 01:43:22 +02:00
SilhouettedObject = ToSilhouette(SelectedTowerPrefab);
2024-04-20 19:22:54 +02:00
2024-04-20 20:12:06 +02:00
// Sets tower rotation
Quaternion newRotation = Quaternion.AngleAxis(CurrentRotation * 90f, transform.up);
SilhouettedObject.transform.localRotation = newRotation;
2024-04-21 01:43:22 +02:00
Vector3 offset = SelectedTowerPrefab.transform.position;
2024-04-20 20:12:06 +02:00
2024-04-20 19:22:54 +02:00
//SilhouettedObject.SetActive(true);
SilhouettedObject.transform.parent = slot.TowerSpawnPoint.transform;
2024-04-20 20:12:06 +02:00
SilhouettedObject.transform.localPosition = offset;
2024-04-20 16:27:58 +02:00
}
2024-04-20 17:13:17 +02:00
2024-04-20 19:22:54 +02:00
public void OnSlotUnHovered(SlotManager slot, GridManager grid, int x, int y)
2024-04-20 17:13:17 +02:00
{
2024-04-21 02:16:52 +02:00
Destroy(SilhouettedObject);
2024-04-20 17:13:17 +02:00
}
2024-04-21 03:07:29 +02:00
public void FinishBuild()
{
Destroy(SilhouettedObject);
OnTowerPlaced?.Invoke(SelectedTowerInfo);
}
2024-04-20 18:04:55 +02:00
2024-04-20 17:13:17 +02:00
[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<Component>();
objScripts = objScripts.Concat(obj.GetComponentsInChildren<Component>()).ToArray();
for (int i = 0; i < objScripts.Length; i++)
{
var comp = objScripts[i];
2024-04-21 03:21:23 +02:00
if (comp is not Renderer && comp is not Transform && comp is not MeshFilter && comp is not UIBehaviour)
2024-04-20 17:13:17 +02:00
{
Destroy(comp);
}
else if (typeof(Renderer).IsAssignableFrom(comp))
{
var renderer = comp as Renderer;
2024-04-20 17:26:20 +02:00
renderer.materials = new Material[] { SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial , SilhouetteMaterial };
2024-04-20 17:13:17 +02:00
}
}
return obj;
}
2024-04-20 01:51:12 +02:00
}