타워 건설 로직 및 구조 변경

타워 건설 시 바닥과의 높이 정렬을 코드로 자동화 함
타워 건설 시 프로그레스 바가 타워 크기에 영향을 받지 않도록 함
프로그레스 바를 직사각형으로 변경
This commit is contained in:
2026-01-15 14:54:51 +09:00
parent ea9b357399
commit f83d5d234b
16 changed files with 2413 additions and 2824 deletions

View File

@@ -121,13 +121,19 @@ public class BuildManager : MonoBehaviour
private void CreateGhost()
{
if (selectedTurret.ghostPrefab == null) return;
if (_ghostInstance != null) Destroy(_ghostInstance);
_ghostInstance = Instantiate(selectedTurret.ghostPrefab);
// [추가] 고스트의 크기도 데이터에 맞게
_ghostInstance.transform.localScale = new Vector3(selectedTurret.size.x, 1f, selectedTurret.size.y);
// 1. 스케일 먼저
Transform visual = _ghostInstance.transform.Find("Visual");
if (visual != null)
{
visual.localScale = new Vector3(selectedTurret.size.x, 1f, selectedTurret.size.y);
}
// 2. 그 다음 바닥 정렬 호출 (yOffset은 데이터에서 가져오거나 0 전달)
AlignToGround(_ghostInstance, 0f);
}
private void DestroyGhost()
@@ -177,23 +183,32 @@ public class BuildManager : MonoBehaviour
for (int y = 0; y < data.size.y; y++)
_occupiedNodes.Add(new Vector2Int(gridPos.x + x, gridPos.y + y));
// 3. 토대 생성
// 3. 토대 생성 (위치는 GridToWorld로 정확히 잡되, 스케일은 건드리지 않음)
GameObject siteObj = Instantiate(constructionSitePrefab, GridToWorld(gridPos, data.size), Quaternion.identity);
// [추가] 토대의 비주얼 크기를 타워 사이즈에 맞게
// x와 z는 타워의 가로/세로 사이즈를 따르고, y(높이)는 1로 유지합니다.
siteObj.transform.localScale = new Vector3(data.size.x, 1f, data.size.y);
// [수정] 최상단 siteObj 대신 자식인 "Visual"의 크기만
Transform visual = siteObj.transform.Find("Visual");
if (visual != null)
{
visual.localScale = new Vector3(data.size.x, 1f, data.size.y);
}
else
{
// 만약 Visual 오브젝트를 못 찾았다면, 개발 중 실수를 방지하기 위해 경고를 띄웁니다.
Debug.LogWarning("BuildManager: 토대 프리팹에서 'Visual' 자식을 찾을 수 없습니다.");
// 차선책으로 전체를 키움 (기존 로직)
siteObj.transform.localScale = new Vector3(data.size.x, 1f, data.size.y);
}
// 4. 컴포넌트 존재 여부 체크
// 토대 바닥 정렬
AlignToGround(siteObj, 0f);
// 4. 컴포넌트 초기화
ConstructionSite siteScript = siteObj.GetComponent<ConstructionSite>();
if (siteScript != null)
{
siteScript.Initialize(data.finalPrefab, data.buildTime, data.size);
}
else
{
Debug.LogError("BuildManager: 생성된 토대 프리팹에 ConstructionSite 스크립트가 없습니다!");
}
ToggleBuildMode();
}
@@ -250,4 +265,24 @@ public class BuildManager : MonoBehaviour
}
}
}
private void AlignToGround(GameObject obj, float yOffset)
{
Transform visual = obj.transform.Find("Visual");
if (visual == null) return;
// Visual 자식 아래에 있는 모든 MeshRenderer를 찾아서 전체 범위를 계산
MeshRenderer[] renderers = visual.GetComponentsInChildren<MeshRenderer>();
if (renderers.Length == 0) return;
Bounds bounds = renderers[0].bounds;
foreach (var renderer in renderers)
{
bounds.Encapsulate(renderer.bounds);
}
// 모델의 가장 바닥(bounds.min.y)이 0이 되도록 차이만큼 올려줌
float bottomY = bounds.min.y - obj.transform.position.y;
visual.localPosition = new Vector3(0, -bottomY + yOffset, 0);
}
}

View File

@@ -19,9 +19,6 @@ public class ConstructionSite : MonoBehaviour
_buildTime = time;
_size = size; // 사이즈 저장
// 토대 자체의 크기 조절 (BuildManager에서 해도 되지만 여기서 하면 더 확실합니다)
transform.localScale = new Vector3(size.x, 1f, size.y);
// UI 생성 및 초기화
if (uiPrefab != null)
{