TowerDefenseGame/Assets/Scriptables/BuildHandler/BuildHandler.cs
2025-06-28 00:23:27 -07:00

130 lines
4.0 KiB
C#

using NUnit.Framework.Constraints;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Tilemaps;
using UnityEngine.UI;
using static Unity.Cinemachine.IInputAxisOwner.AxisDescriptor;
using static UnityEngine.RuleTile.TilingRuleOutput;
[CreateAssetMenu(menuName = "Custom/BuilderHandler", fileName = "NewBuilderHandler")]
public class BuildHandler : ScriptableObject {
[Header("Build Dependencies")]
public GameObject PrefabToSpawn;
public GameObject PrefabToSpawnPreviewAsset;
[Header("VFX Dependencies")]
public VfxHandlerBase Sparkle;
private GameObject PreviewObj;
private Vector3 SnappedPosition;
private bool BuildMode = false;
private Vector2 SpriteSize;
private CapsuleDirection2D CapsuleDirection = CapsuleDirection2D.Vertical;
private void OnEnable() {
InitializePreviewObj();
}
private void InitializePreviewObj() {
PreviewObj = Instantiate(PrefabToSpawnPreviewAsset, new Vector3(), Quaternion.identity);
PreviewObj.SetActive(false);
SpriteRenderer sprite = PreviewObj.GetComponent<SpriteRenderer>();
Sprite s = PreviewObj.GetComponent<SpriteRenderer>().sprite;
Vector2 pivot = s.pivot / s.pixelsPerUnit;
SpriteSize = s.rect.size / s.pixelsPerUnit;
if (SpriteSize.x > SpriteSize.y)
CapsuleDirection = CapsuleDirection2D.Horizontal;
}
public void SetBuildMode(bool mode) {
if (PreviewObj == null) InitializePreviewObj();
PreviewObj.SetActive(mode);
BuildMode = mode;
}
Vector3 GetSnappedPosition(Vector3 worldPos, float gridSize) {
float x = Mathf.Round(worldPos.x / gridSize) * gridSize;
float y = Mathf.Round(worldPos.y / gridSize) * gridSize;
return new Vector3(x, y, 0);
}
public void UpdatePreview(float gridSize) {
if (!BuildMode) return;
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 offset = new Vector3(0, 0, 3);
mousePos += offset;
SnappedPosition = GetSnappedPosition(mousePos, gridSize / 2);
PreviewObj.transform.position = SnappedPosition;
}
public void PlaceObject() {
if (!BuildMode) return;
if (!IsTileUnderMouse()) return;
Collider2D[] hits = Physics2D.OverlapCapsuleAll(SnappedPosition, SpriteSize * 0.8f, CapsuleDirection, 0);
foreach (var hit in hits) {
if (hit.CompareTag("Structural")) {
Debug.Log("Hit building object");
return;
} else {
Debug.Log($"Tag:{hit.tag}");
}
}
hits = Physics2D.OverlapCapsuleAll(SnappedPosition, SpriteSize, CapsuleDirection, 0);
foreach (var hit in hits) {
if (hit.GetComponent<TilemapCollider2D>()) {
Debug.Log("Hit terrain tile");
return;
}
}
Sparkle?.PlayAll(SnappedPosition);
GameObject newObj = Instantiate(PrefabToSpawn, SnappedPosition, Quaternion.identity);
SpriteRenderer image = newObj.GetComponent<SpriteRenderer>();
}
public bool IsTileUnderMouse() {
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = 0f;
GameObject groundGO = GameObject.FindGameObjectWithTag("Ground");
if (!groundGO) return false;
Tilemap tilemap = groundGO.GetComponent<Tilemap>();
if (!tilemap) return false;
Vector3Int cellPos = tilemap.WorldToCell(worldPos);
TileBase tile = tilemap.GetTile(cellPos);
if (!tile) return false;
return tile;
}
public void DrawGizmos() {
Vector2 center = SnappedPosition;
Vector2 size = SpriteSize;
float radius = size.x / 2 * 0.8f;
float height = size.y / 2 * 0.8f;
if (SpriteSize.x != SpriteSize.y) {
Vector2 top = center + Vector2.up * (height / 2 - radius);
Vector2 bottom = center + Vector2.down * (height / 2 - radius);
Gizmos.color = Color.green;
Gizmos.DrawWireCube(center, new Vector2(size.x, height - 2 * radius));
Gizmos.DrawWireSphere(top, radius);
Gizmos.DrawWireSphere(bottom, radius);
} else {
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(center, radius);
}
}
}