using UnityEngine; using UnityEngine.Tilemaps; public class BuilderManager : 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(); 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()) // 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()) 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(); 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); } } }