TowerDefenseGame/Assets/Scripts/Runtime/Characters/Player/Building/BuilderHandlerRunner.cs
Nico a52bbb0849 Create object pooling system
Optimize VFX and builder handling mechanics
2025-06-28 11:00:01 -07:00

128 lines
3.9 KiB
C#

using UnityEngine;
using UnityEngine.Tilemaps;
public class BuilderHandlerRunner : MonoBehaviour {
public BuilderSettings Settings;
private GameObjectPool GameObjPool;
private GameObject PreviewObj;
private bool BuildMode = false;
private Vector2 SpriteSize;
private CapsuleDirection2D CapsuleDir;
private float GridSize = 0.5f;
private Collider2D[] bufferSmall = new Collider2D[10];
private Collider2D[] bufferLarge = new Collider2D[20];
private ContactFilter2D ContactFilter;
private Vector3 SnappedPos;
private VfxHandlerBase VfxHandler;
void Awake() {
GameObjPool = new GameObjectPool(Settings.ObjToSpawn);
PreviewObj = Instantiate(Settings.ObjAsPreview);
PreviewObj.SetActive(false);
var sr = PreviewObj.GetComponent<SpriteRenderer>();
var s = sr.sprite;
SpriteSize = s.rect.size / s.pixelsPerUnit;
CapsuleDir = SpriteSize.x > SpriteSize.y
? CapsuleDirection2D.Horizontal
: CapsuleDirection2D.Vertical;
ContactFilter = new ContactFilter2D();
//ContactFilter.useLayerMask = true;
//ContactFilter.layerMask = LayerMask.GetMask("Structural", "Terrain"); // only check these layers
ContactFilter.useTriggers = false; // ignore triggers
ContactFilter.useDepth = true;
ContactFilter.SetDepth(-Mathf.Infinity, Mathf.Infinity);
VfxHandler = new VfxHandlerBase(Settings.Vfx);
}
void Update() {
if (!BuildMode) return;
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
SnappedPos = new Vector3(
Mathf.Round(mousePos.x / GridSize) * GridSize,
Mathf.Round(mousePos.y / GridSize) * GridSize,
0f);
PreviewObj.transform.position = SnappedPos;
if (Input.GetMouseButtonDown(0)) PlaceObject();
}
public void SetBuildMode(bool on) {
BuildMode = on;
PreviewObj.SetActive(on);
}
void PlaceObject() {
if (InvalidPlacement()) return;
VfxHandler.PlayAll(SnappedPos);
var obj = GameObjPool.Get(SnappedPos, Quaternion.identity);
}
private bool InvalidPlacement() {
//Collider2D[] hits = Physics2D.OverlapCapsuleAll(pos, SpriteSize * 0.8f, CapsuleDir, 0);
//foreach (var hit in hits)
// if (hit.CompareTag("Structural"))
// return false;
//hits = Physics2D.OverlapCapsuleAll(pos, SpriteSize, CapsuleDir, 0);
//foreach (var hit in hits)
// if (hit.GetComponent<TilemapCollider2D>())
// return false;
int count = Physics2D.OverlapCapsule(SnappedPos, SpriteSize * 0.8f, CapsuleDir, 0f, ContactFilter, bufferSmall);
for (int i = 0; i < count; i++)
if (bufferSmall[i].CompareTag("Structural"))
return true;
count = Physics2D.OverlapCapsule(SnappedPos, SpriteSize, CapsuleDir, 0f, ContactFilter, bufferLarge);
for (int i = 0; i < count; i++)
if (bufferLarge[i].GetComponent<TilemapCollider2D>())
return true;
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = 0f;
GameObject groundGO = GameObject.FindGameObjectWithTag("Ground");
if (!groundGO) return true;
Tilemap tilemap = groundGO.GetComponent<Tilemap>();
if (!tilemap) return true;
Vector3Int cellPos = tilemap.WorldToCell(worldPos);
TileBase tile = tilemap.GetTile(cellPos);
if (!tile) return true;
return false;
}
void OnDrawGizmos() {
Vector2 center = SnappedPos;
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);
}
}
}