적과 타워가 서로 공격하지 않는 문제 수정
This commit is contained in:
@@ -22,6 +22,10 @@ namespace Northbound
|
||||
private List<Building> placedBuildings = new List<Building>();
|
||||
private List<BuildingFoundation> placedFoundations = new List<BuildingFoundation>();
|
||||
|
||||
// Level 1 건물 캐시
|
||||
private List<TowerData> _buildableBuildingsCache;
|
||||
private bool _buildableCacheDirty = true;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
@@ -41,6 +45,26 @@ namespace Northbound
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 건설 가능한 건물 목록 반환 (Level 1만, 캐싱됨)
|
||||
/// </summary>
|
||||
public List<TowerData> GetBuildableBuildings()
|
||||
{
|
||||
if (_buildableCacheDirty || _buildableBuildingsCache == null)
|
||||
{
|
||||
_buildableBuildingsCache = new List<TowerData>();
|
||||
foreach (var building in availableBuildings)
|
||||
{
|
||||
if (building != null && building.level == 1)
|
||||
{
|
||||
_buildableBuildingsCache.Add(building);
|
||||
}
|
||||
}
|
||||
_buildableCacheDirty = false;
|
||||
}
|
||||
return _buildableBuildingsCache;
|
||||
}
|
||||
|
||||
public Vector3Int WorldToGrid(Vector3 worldPosition)
|
||||
{
|
||||
return new Vector3Int(
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Northbound
|
||||
public void SetSelectedBuilding(int index)
|
||||
{
|
||||
if (index < 0 || BuildingManager.Instance == null ||
|
||||
index >= BuildingManager.Instance.availableBuildings.Count)
|
||||
index >= BuildingManager.Instance.GetBuildableBuildings().Count)
|
||||
{
|
||||
Debug.LogWarning($"[BuildingPlacement] 유효하지 않은 건물 인덱스: {index}");
|
||||
return;
|
||||
@@ -235,19 +235,22 @@ namespace Northbound
|
||||
|
||||
private void CreatePreview()
|
||||
{
|
||||
// 기존 프리뷰가 있다면 먼저 정리 (누적 방지)
|
||||
DestroyPreview();
|
||||
|
||||
if (BuildingManager.Instance == null)
|
||||
{
|
||||
Debug.LogWarning("[BuildingPlacement] BuildingManager가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count)
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.GetBuildableBuildings().Count)
|
||||
{
|
||||
Debug.LogWarning($"[BuildingPlacement] 유효하지 않은 건물 인덱스: {selectedBuildingIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
TowerData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex];
|
||||
TowerData data = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogError($"[BuildingPlacement] TowerData is NULL at index {selectedBuildingIndex}");
|
||||
@@ -262,6 +265,9 @@ namespace Northbound
|
||||
|
||||
// 완성 건물 프리팹으로 프리뷰 생성 (사용자가 완성 모습을 볼 수 있도록)
|
||||
previewObject = Instantiate(data.prefab);
|
||||
|
||||
// (0,0,0)에 고스트가 보이지 않도록 처음에는 비활성화
|
||||
previewObject.SetActive(false);
|
||||
|
||||
// Remove NetworkObject component from preview
|
||||
NetworkObject netObj = previewObject.GetComponent<NetworkObject>();
|
||||
@@ -317,17 +323,19 @@ namespace Northbound
|
||||
if (previewObject == null || BuildingManager.Instance == null)
|
||||
return;
|
||||
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count)
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.GetBuildableBuildings().Count)
|
||||
return;
|
||||
|
||||
TowerData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex];
|
||||
TowerData data = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
if (data == null || data.prefab == null)
|
||||
return;
|
||||
|
||||
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
||||
|
||||
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, maxPlacementDistance, groundLayer))
|
||||
{
|
||||
// Raycast 성공 시 프리뷰 표시
|
||||
previewObject.SetActive(true);
|
||||
|
||||
// Check if placement is valid
|
||||
bool isValid = BuildingManager.Instance.IsValidPlacement(data, hit.point, currentRotation, out Vector3 snappedPosition);
|
||||
@@ -352,6 +360,11 @@ namespace Northbound
|
||||
renderer.materials = mats;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Raycast 실패 시 (0,0,0)에 고스트가 보이지 않도록 프리뷰 숨김
|
||||
previewObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRotate(InputAction.CallbackContext context)
|
||||
@@ -443,13 +456,13 @@ namespace Northbound
|
||||
{
|
||||
if (BuildingManager.Instance == null) return;
|
||||
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count)
|
||||
if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.GetBuildableBuildings().Count)
|
||||
{
|
||||
Debug.LogWarning($"[BuildingPlacement] Invalid building index: {selectedBuildingIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
TowerData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex];
|
||||
TowerData data = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
if (data == null || data.prefab == null)
|
||||
{
|
||||
Debug.LogError($"[BuildingPlacement] TowerData or prefab is null at index {selectedBuildingIndex}. Please run 'Northbound > Populate Towers from Prefabs' and update BuildingManager.");
|
||||
@@ -581,7 +594,7 @@ namespace Northbound
|
||||
return;
|
||||
}
|
||||
|
||||
TowerData selectedData = BuildingManager.Instance.availableBuildings[selectedBuildingIndex];
|
||||
TowerData selectedData = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
|
||||
// Check affordability
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
@@ -629,7 +642,7 @@ namespace Northbound
|
||||
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, maxPlacementDistance, groundLayer))
|
||||
{
|
||||
TowerData selectedData = BuildingManager.Instance.availableBuildings[selectedBuildingIndex];
|
||||
TowerData selectedData = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
|
||||
// Check affordability
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using TMPro;
|
||||
@@ -188,12 +187,12 @@ namespace Northbound
|
||||
}
|
||||
slotButtons.Clear();
|
||||
|
||||
// 모든 건물 슬롯 생성 (제한 없음)
|
||||
var buildings = BuildingManager.Instance.availableBuildings;
|
||||
|
||||
for (int i = 0; i < buildings.Count; i++)
|
||||
// Level 1 건물만 슬롯 생성 (건설 모드에서는 기본 건물만 표시)
|
||||
var buildableBuildings = BuildingManager.Instance.GetBuildableBuildings();
|
||||
|
||||
for (int i = 0; i < buildableBuildings.Count; i++)
|
||||
{
|
||||
CreateSlot(buildings[i], i);
|
||||
CreateSlot(buildableBuildings[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Northbound
|
||||
|
||||
public string GetInteractionPrompt()
|
||||
{
|
||||
return "[F] 업그레이드";
|
||||
return "[F] Upgrade";
|
||||
}
|
||||
|
||||
public string GetInteractionAnimation()
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Northbound
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Player 감지 (코어로 가는 도중에도 Player를 타겟팅)
|
||||
// 1. Player 감지 (코어로 가는 도중에도 Player/건물을 타겟팅)
|
||||
GameObject detectedPlayer = DetectTarget();
|
||||
if (detectedPlayer != null)
|
||||
{
|
||||
@@ -189,20 +189,7 @@ namespace Northbound
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 코어로 가는 경로가 '완전(Complete)'한지 확인
|
||||
// NavMesh가 갱신되었다면 에이전트는 즉시 Complete 상태가 됩니다.
|
||||
if (_agent.hasPath && _agent.pathStatus == NavMeshPathStatus.PathComplete)
|
||||
{
|
||||
if (!_hasSetCoreDestination)
|
||||
{
|
||||
_agent.SetDestination(_core.GetNavMeshPosition());
|
||||
_hasSetCoreDestination = true;
|
||||
}
|
||||
// [중요] 길이 열렸으므로 아래의 장애물 탐지 로직을 아예 실행하지 않고 리턴!
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 길이 막혔을 때(Partial)만 아주 좁은 범위에서 장애물을 찾음
|
||||
// 2. 경로 상의 장애물(건물) 감지 - 경로 상태와 관계없이 확인
|
||||
GameObject obstacle = DetectObstacle();
|
||||
if (obstacle != null)
|
||||
{
|
||||
@@ -211,8 +198,8 @@ namespace Northbound
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 경로가 유효하지 않을 때만 재설정
|
||||
if (!_agent.hasPath || _agent.pathStatus == NavMeshPathStatus.PathInvalid)
|
||||
// 3. 코어로 가는 경로 설정
|
||||
if (!_hasSetCoreDestination || !_agent.hasPath || _agent.pathStatus == NavMeshPathStatus.PathInvalid)
|
||||
{
|
||||
_agent.SetDestination(_core.GetNavMeshPosition());
|
||||
_hasSetCoreDestination = true;
|
||||
|
||||
Reference in New Issue
Block a user