Files
CityBuilder/Assets/Scripts/BuildingPlacement.cs

177 lines
6.5 KiB
C#

using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering.UI;
using UnityEngine.UI;
public class BuildingPlacement : MonoBehaviour
{
public static BuildingPlacement Instance { get; private set; }
void Awake()
{
Instance = this;
}
public GameObject bulldozerIndicator;
[SerializeField] private Material placementIndicatorMaterial;
[SerializeField] private Material errorIndicatorMaterial;
[SerializeField] private Button OptionA;
[SerializeField] private Button OptionB;
[SerializeField] private Button OptionC;
[SerializeField] private Button OptionD;
[SerializeField] private GameObject rightClickMenu;
public bool currentlyPlacing;
private bool currentlyBulldozering;
private BuildingPreset curBuildingPreset;
private float indicatorUpdateRate = 0.05f;
private float lastUpdateTime;
private Vector3 curIndicatorPos;
public Quaternion curIndicatorRotation;
public GameObject placementPrefab;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
//cancel building placement
if (Input.GetKeyDown(KeyCode.Escape))
{
CancelBuildingPlacement();
}
//called every 0.05 seconds
if (Time.time - lastUpdateTime > indicatorUpdateRate)
{
lastUpdateTime = Time.time;
//get the currently selected tile position
curIndicatorPos = Selector.Instance.GetCurTilePosition();
//move the placement indicator or bulldozer indicator to the selected tile
if (currentlyPlacing && placementPrefab != null)
{
placementPrefab.transform.position = curIndicatorPos;
placementPrefab.transform.rotation = curIndicatorRotation;
var renderer = placementPrefab.GetComponentInChildren<Renderer>();
if (renderer != null)
{
//check if the position is valid for placement
if (City.Instance.buildings.Exists(x => x.transform.position == curIndicatorPos))
{
//if the position is not valid, change the material to the error material
renderer.material = errorIndicatorMaterial;
}
else
{
//if the position is valid, change the material back to the placement material
renderer.material = placementIndicatorMaterial;
}
}
}
else if (currentlyBulldozering)
{
bulldozerIndicator.transform.position = curIndicatorPos;
}
}
//called when player left clicks
if (Input.GetMouseButton(0) && currentlyPlacing)
{
PlaceBuilding();
}
else if (Input.GetMouseButton(0) && currentlyBulldozering)
{
Bulldoze();
}
}
//Called when the player presses a building UI button
public void BeginNewBuildingPlacement(BuildingPreset preset)
{
// Cancel any current placement
if (currentlyPlacing)
{
CancelBuildingPlacement();
rightClickMenu.SetActive(false); // Hide the right-click menu if it was open
}
// Cancel bulldozing if active
if (currentlyBulldozering)
{
ToggleBulldoze();
}
rightClickMenu.SetActive(true); // Hide the right-click menu if it was open
// Check if the player has enough money
if (ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Money).resourceAmount < preset.buildCost)
{
return;
}
currentlyPlacing = true;
curBuildingPreset = preset;
// Destroy previous placement preview if it exists
if (placementPrefab != null)
{
Destroy(placementPrefab);
}
// Instantiate a preview object for placement
placementPrefab = Instantiate(preset.prefab);
// Optionally, set a special material for preview
var renderer = placementPrefab.GetComponent<Renderer>();
if (placementIndicatorMaterial != null && renderer != null)
{
renderer.material = placementIndicatorMaterial;
}
placementPrefab.transform.position = new Vector3(0, -99, 0);
placementPrefab.transform.rotation = Quaternion.identity;
}
//Called when the player places down a building or presses Escape
void CancelBuildingPlacement()
{
currentlyPlacing = false;
// Destroy the placement preview if it exists
if (placementPrefab != null)
{
Destroy(placementPrefab);
placementPrefab = null;
rightClickMenu.SetActive(false); // Hide the right-click menu if it was open
}
}
//Turn the Bulldozer on or off
public void ToggleBulldoze()
{
currentlyBulldozering = !currentlyBulldozering;
//enable the bulldozer indicator
bulldozerIndicator.SetActive(currentlyBulldozering);
bulldozerIndicator.transform.position = new Vector3(0, -99, 0);
}
//places down the currently selected building
void PlaceBuilding()
{
// Check if the player is trying to place a building on top of another building
if (City.Instance.buildings.Exists(x => x.transform.position == curIndicatorPos))
{
Debug.Log("Cannot place building on top of another building!");
return;
}
// Check if the player has enough money before placing
var moneyResource = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Money);
if (moneyResource == null || moneyResource.resourceAmount < curBuildingPreset.buildCost)
{
Debug.Log("Not enough money to place this building!");
return;
}
GameObject buildingObj = Instantiate(curBuildingPreset.prefab, curIndicatorPos, curIndicatorRotation);
City.Instance.OnPlaceBuilding(buildingObj.GetComponent<Building>());
}
//deletes the currently selected building
void Bulldoze()
{
Building buildingToDestroy = City.Instance.buildings.Find(x => x.transform.position == curIndicatorPos);
if (buildingToDestroy != null)
{
City.Instance.OnRemoveBuilding(buildingToDestroy);
}
}
}