건설 모드에서 클릭이 잘 작동하지 않는 문제 수정
건설 모드 UI가 클릭되어 건설되지 않는 문제 수정 JMO Asset 위치 조정 Tower, Monster, Creep의 Hit/Destroy FX Prefab 설정 (Template Level) Tower에 체력바 추가 (최초 건설 시, 체력 변경 시 등장) Tower 관련 디버깅 로그 정리 건설 토대의 사이즈가 비정상적인 문제 수정
This commit is contained in:
@@ -180,14 +180,9 @@ namespace Northbound
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
ulong previousOwner = _ownerId.Value;
|
||||
TeamType previousTeam = _team.Value;
|
||||
|
||||
_ownerId.Value = newOwnerId;
|
||||
_team.Value = newTeam;
|
||||
|
||||
Debug.Log($"<color=yellow>[Building] {buildingData?.buildingName ?? "건물"} 소유권 변경: {previousOwner} → {newOwnerId}, 팀: {TeamManager.GetTeamName(previousTeam)} → {TeamManager.GetTeamName(newTeam)}</color>");
|
||||
|
||||
// 시야 제공자 재등록 (소유자가 바뀌었으므로)
|
||||
if (buildingData != null && buildingData.providesVision)
|
||||
{
|
||||
@@ -212,7 +207,6 @@ namespace Northbound
|
||||
{
|
||||
OnTeamChanged?.Invoke(newValue);
|
||||
UpdateTeamVisuals();
|
||||
Debug.Log($"<color=cyan>[Building] {buildingData?.buildingName ?? "건물"} 팀 변경: {TeamManager.GetTeamName(previousValue)} → {TeamManager.GetTeamName(newValue)}</color>");
|
||||
}
|
||||
|
||||
private void UpdateTeamVisuals()
|
||||
@@ -260,7 +254,6 @@ namespace Northbound
|
||||
// 무적 건물
|
||||
if (buildingData != null && buildingData.isIndestructible)
|
||||
{
|
||||
Debug.Log($"<color=yellow>[Building] {buildingData.buildingName}은(는) 무적입니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -271,12 +264,11 @@ namespace Northbound
|
||||
// 공격자의 팀 확인 (팀 공격 방지)
|
||||
var attackerObj = NetworkManager.Singleton.SpawnManager.SpawnedObjects[attackerId];
|
||||
var attackerTeamMember = attackerObj?.GetComponent<ITeamMember>();
|
||||
|
||||
|
||||
if (attackerTeamMember != null)
|
||||
{
|
||||
if (!TeamManager.CanAttack(attackerTeamMember, this))
|
||||
{
|
||||
Debug.Log($"<color=yellow>[Building] {TeamManager.GetTeamName(attackerTeamMember.GetTeam())} 팀은 {TeamManager.GetTeamName(_team.Value)} 팀을 공격할 수 없습니다.</color>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -285,8 +277,6 @@ namespace Northbound
|
||||
int actualDamage = Mathf.Min(damage, _currentHealth.Value);
|
||||
_currentHealth.Value -= actualDamage;
|
||||
|
||||
Debug.Log($"<color=red>[Building] {buildingData?.buildingName ?? "건물"} ({TeamManager.GetTeamName(_team.Value)})이(가) {actualDamage} 데미지를 받았습니다. 남은 체력: {_currentHealth.Value}/{buildingData?.maxHealth ?? 100}</color>");
|
||||
|
||||
// 데미지 이펙트
|
||||
ShowDamageEffectClientRpc();
|
||||
|
||||
@@ -315,8 +305,6 @@ namespace Northbound
|
||||
if (!IsServer)
|
||||
return;
|
||||
|
||||
Debug.Log($"<color=red>[Building] {buildingData?.buildingName ?? "건물"} ({TeamManager.GetTeamName(_team.Value)})이(가) 파괴되었습니다! (공격자: {attackerId})</color>");
|
||||
|
||||
// 파괴 이벤트 발생
|
||||
OnDestroyed?.Invoke();
|
||||
NotifyDestroyedClientRpc();
|
||||
@@ -361,8 +349,6 @@ namespace Northbound
|
||||
|
||||
int healAmount = Mathf.Min(amount, buildingData.maxHealth - _currentHealth.Value);
|
||||
_currentHealth.Value += healAmount;
|
||||
|
||||
Debug.Log($"<color=green>[Building] {buildingData.buildingName}이(가) {healAmount} 회복되었습니다. 현재 체력: {_currentHealth.Value}/{buildingData.maxHealth}</color>");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -398,6 +384,11 @@ namespace Northbound
|
||||
if (_healthBar != null)
|
||||
return;
|
||||
|
||||
if (healthBarPrefab == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject healthBarObj = Instantiate(healthBarPrefab, transform);
|
||||
_healthBar = healthBarObj.GetComponent<BuildingHealthBar>();
|
||||
|
||||
@@ -411,7 +402,9 @@ namespace Northbound
|
||||
{
|
||||
if (_healthBar != null)
|
||||
{
|
||||
_healthBar.UpdateHealth(_currentHealth.Value, GetMaxHealth());
|
||||
int current = _currentHealth.Value;
|
||||
int max = GetMaxHealth();
|
||||
_healthBar.UpdateHealth(current, max);
|
||||
}
|
||||
|
||||
OnHealthChanged?.Invoke(_currentHealth.Value, GetMaxHealth());
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Northbound
|
||||
public float heightOffset = 3f;
|
||||
public bool hideWhenFull = true;
|
||||
public float hideDelay = 3f;
|
||||
public float initialShowDuration = 2f; // 건설 완료 시 체력바 표시 시간
|
||||
|
||||
[Header("Colors")]
|
||||
public Color fullHealthColor = Color.green;
|
||||
@@ -28,8 +29,9 @@ namespace Northbound
|
||||
|
||||
private Building _building;
|
||||
private Camera _mainCamera;
|
||||
private float _lastDamageTime;
|
||||
private float _lastShowTime;
|
||||
private Canvas _canvas;
|
||||
private bool _initialized = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -59,6 +61,28 @@ namespace Northbound
|
||||
{
|
||||
_building = building;
|
||||
transform.localPosition = Vector3.up * heightOffset;
|
||||
|
||||
// 건설 완료 시 체력바 표시
|
||||
ShowBar(initialShowDuration);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 체력바를 지정된 시간 동안 표시
|
||||
/// </summary>
|
||||
public void ShowBar(float duration = 0f)
|
||||
{
|
||||
if (barContainer != null)
|
||||
{
|
||||
barContainer.SetActive(true);
|
||||
_lastShowTime = Time.time;
|
||||
|
||||
// duration이 0보다 크면 그 시간 동안만 표시
|
||||
if (duration > 0)
|
||||
{
|
||||
_lastShowTime = Time.time + duration - hideDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateHealth(int currentHealth, int maxHealth)
|
||||
@@ -77,12 +101,8 @@ namespace Northbound
|
||||
healthText.text = $"{currentHealth}/{maxHealth}";
|
||||
}
|
||||
|
||||
// 체력바 표시/숨김
|
||||
if (barContainer != null)
|
||||
{
|
||||
_lastDamageTime = Time.time;
|
||||
barContainer.SetActive(true);
|
||||
}
|
||||
// 체력 변경 시 체력바 표시
|
||||
ShowBar();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
@@ -94,11 +114,11 @@ namespace Northbound
|
||||
}
|
||||
|
||||
// 체력이 가득 차면 숨김
|
||||
if (hideWhenFull && barContainer != null && _building != null)
|
||||
if (hideWhenFull && barContainer != null && _building != null && _initialized)
|
||||
{
|
||||
float healthPercentage = _building.GetHealthPercentage();
|
||||
|
||||
if (healthPercentage >= 1f && Time.time - _lastDamageTime > hideDelay)
|
||||
|
||||
if (healthPercentage >= 1f && Time.time - _lastShowTime > hideDelay)
|
||||
{
|
||||
barContainer.SetActive(false);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,9 @@ namespace Northbound
|
||||
|
||||
// Ground check
|
||||
if (!CheckGround(position, out groundPosition))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// IMPORTANT: Snap to grid BEFORE checking overlap!
|
||||
// Otherwise we check the raw cursor position which might overlap
|
||||
@@ -119,7 +121,9 @@ namespace Northbound
|
||||
Bounds buildingGridBounds = building.GetGridBounds();
|
||||
|
||||
if (checkBounds.Intersects(buildingGridBounds))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 토대와의 충돌 체크
|
||||
@@ -130,7 +134,9 @@ namespace Northbound
|
||||
Bounds foundationGridBounds = foundation.GetGridBounds();
|
||||
|
||||
if (checkBounds.Intersects(foundationGridBounds))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 물리적 충돌 체크 (플레이어, 유닛, 기타 오브젝트와의 충돌)
|
||||
@@ -197,14 +203,12 @@ namespace Northbound
|
||||
// 보안 검증 1: 유효한 클라이언트인지 확인
|
||||
if (!NetworkManager.Singleton.ConnectedClients.ContainsKey(requestingClientId))
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 유효하지 않은 클라이언트 ID: {requestingClientId}</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
// 보안 검증 2: 건물 인덱스 유효성 확인
|
||||
if (buildingIndex < 0 || buildingIndex >= availableBuildings.Count)
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 유효하지 않은 건물 인덱스: {buildingIndex} (클라이언트: {requestingClientId})</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -213,7 +217,6 @@ namespace Northbound
|
||||
// 보안 검증 3: 건물 데이터 유효성 확인
|
||||
if (data == null || data.prefab == null)
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 건물 데이터가 유효하지 않습니다. (클라이언트: {requestingClientId})</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -221,13 +224,11 @@ namespace Northbound
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
if (coreResourceManager == null)
|
||||
{
|
||||
Debug.LogWarning("<color=red>[BuildingManager] CoreResourceManager 인스턴스를 찾을 수 없습니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!coreResourceManager.CanAfford(data.mana))
|
||||
{
|
||||
Debug.LogWarning($"<color=yellow>[BuildingManager] 코어 자원이 부족합니다. 필요: {data.mana} (클라이언트: {requestingClientId})</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -236,7 +237,6 @@ namespace Northbound
|
||||
// 배치 가능 여부 확인
|
||||
if (!IsValidPlacement(data, position, rotation, out Vector3 snappedPosition))
|
||||
{
|
||||
Debug.LogWarning($"<color=yellow>[BuildingManager] 건물 배치 불가능 위치 (클라이언트: {requestingClientId})</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -268,8 +268,6 @@ namespace Northbound
|
||||
// 건물 초기화
|
||||
building.Initialize(data, gridPosition, rotation, requestingClientId);
|
||||
placedBuildings.Add(building);
|
||||
|
||||
Debug.Log($"<color=green>[BuildingManager] {data.buildingName} 건설 완료 (소유자: {requestingClientId}, 위치: {gridPosition})</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -283,7 +281,6 @@ namespace Northbound
|
||||
if (placedBuildings.Contains(building))
|
||||
{
|
||||
placedBuildings.Remove(building);
|
||||
Debug.Log($"<color=yellow>[BuildingManager] 건물 제거됨: {building.buildingData?.buildingName ?? "Unknown"}</color>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +292,6 @@ namespace Northbound
|
||||
if (placedFoundations.Contains(foundation))
|
||||
{
|
||||
placedFoundations.Remove(foundation);
|
||||
Debug.Log($"<color=yellow>[BuildingManager] 토대 제거됨: {foundation.buildingData?.buildingName ?? "Unknown"}</color>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +303,6 @@ namespace Northbound
|
||||
if (!placedBuildings.Contains(building))
|
||||
{
|
||||
placedBuildings.Add(building);
|
||||
Debug.Log($"<color=cyan>[BuildingManager] 사전 배치 건물 등록: {building.buildingData?.buildingName ?? building.gameObject.name}</color>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,14 +360,12 @@ namespace Northbound
|
||||
// 보안 검증 1: 유효한 클라이언트인지 확인
|
||||
if (!NetworkManager.Singleton.ConnectedClients.ContainsKey(requestingClientId))
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 유효하지 않은 클라이언트 ID: {requestingClientId}</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
// 보안 검증 2: 건물 인덱스 유효성 확인
|
||||
if (buildingIndex < 0 || buildingIndex >= availableBuildings.Count)
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 유효하지 않은 건물 인덱스: {buildingIndex}</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -381,7 +374,6 @@ namespace Northbound
|
||||
// 보안 검증 3: 건물 데이터 유효성 확인
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogWarning($"<color=red>[BuildingManager] 건물 데이터가 유효하지 않습니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -389,13 +381,11 @@ namespace Northbound
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
if (coreResourceManager == null)
|
||||
{
|
||||
Debug.LogWarning("<color=red>[BuildingManager] CoreResourceManager 인스턴스를 찾을 수 없습니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!coreResourceManager.CanAfford(data.mana))
|
||||
{
|
||||
Debug.LogWarning($"<color=yellow>[BuildingManager] 코어 자원이 부족합니다. 필요: {data.mana}</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -411,7 +401,8 @@ namespace Northbound
|
||||
// 배치 가능 여부 확인
|
||||
if (!IsValidPlacement(data, position, rotation, out Vector3 snappedPosition))
|
||||
{
|
||||
Debug.LogWarning($"<color=yellow>[BuildingManager] 토대 배치 불가능 위치</color>");
|
||||
// 자원 환불
|
||||
coreResourceManager.AddResources(data.mana);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -523,8 +514,6 @@ namespace Northbound
|
||||
// 건물 초기화
|
||||
building.Initialize(data, gridPosition, rotation, ownerId);
|
||||
placedBuildings.Add(building);
|
||||
|
||||
Debug.Log($"<color=green>[BuildingManager] {data.buildingName} 건설 완료! (소유자: {ownerId}, 위치: {gridPosition}, 팀: {team})</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -42,6 +42,9 @@ namespace Northbound
|
||||
private List<GameObject> dragPreviewObjects = new List<GameObject>();
|
||||
private List<Vector3> dragBuildingPositions = new List<Vector3>();
|
||||
|
||||
// UI 체크 캐싱 (Input System 콜백 내에서 IsPointerOverGameObject() 사용 불가)
|
||||
private bool _isPointerOverUI = false;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (!IsOwner) return;
|
||||
@@ -133,6 +136,9 @@ namespace Northbound
|
||||
{
|
||||
if (!IsOwner) return;
|
||||
|
||||
// UI 체크 캐싱 (Input System 콜백 내에서 사용하기 위해)
|
||||
_isPointerOverUI = CheckPointerOverUI();
|
||||
|
||||
if (isBuildModeActive)
|
||||
{
|
||||
if (isDragging && enableDragBuilding)
|
||||
@@ -152,7 +158,6 @@ namespace Northbound
|
||||
if (isDragging && isBuildModeActive)
|
||||
{
|
||||
CancelDrag();
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 드래그 건설 취소됨</color>");
|
||||
}
|
||||
// 건설 모드 활성화 상태면 건설 모드 종료
|
||||
else if (isBuildModeActive)
|
||||
@@ -164,7 +169,6 @@ namespace Northbound
|
||||
}
|
||||
DestroyPreview();
|
||||
ClearDragPreviews();
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 건설 모드 취소됨</color>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +198,6 @@ namespace Northbound
|
||||
if (isDragging)
|
||||
{
|
||||
CancelDrag();
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 건설 모드 종료로 드래그 취소됨</color>");
|
||||
}
|
||||
|
||||
DestroyPreview();
|
||||
@@ -221,7 +224,6 @@ namespace Northbound
|
||||
if (isDragging)
|
||||
{
|
||||
CancelDrag();
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 건물 변경으로 드래그 취소됨</color>");
|
||||
}
|
||||
|
||||
// 프리뷰 다시 생성
|
||||
@@ -372,18 +374,14 @@ namespace Northbound
|
||||
if (!isBuildModeActive) return;
|
||||
|
||||
// 드래그 중에는 회전 불가
|
||||
if (isDragging)
|
||||
{
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 드래그 중에는 회전할 수 없습니다</color>");
|
||||
return;
|
||||
}
|
||||
if (isDragging) return;
|
||||
|
||||
currentRotation = (currentRotation + 1) % 4;
|
||||
}
|
||||
|
||||
private void OnBuildPressed(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isBuildModeActive || IsPointerOverUI())
|
||||
if (!isBuildModeActive || _isPointerOverUI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -396,14 +394,12 @@ namespace Northbound
|
||||
{
|
||||
isDragging = true;
|
||||
dragStartPosition = hit.point;
|
||||
|
||||
|
||||
// 메인 프리뷰 숨기기
|
||||
if (previewObject != null)
|
||||
{
|
||||
previewObject.SetActive(false);
|
||||
}
|
||||
|
||||
Debug.Log("<color=cyan>[BuildingPlacement] 드래그 건설 시작 (ESC로 취소 가능)</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -500,6 +496,9 @@ namespace Northbound
|
||||
|
||||
GameObject preview = Instantiate(data.prefab);
|
||||
|
||||
// 프리뷰가 보이도록 명시적으로 활성화
|
||||
preview.SetActive(true);
|
||||
|
||||
// Remove NetworkObject and Building components
|
||||
if (preview.GetComponent<NetworkObject>() != null)
|
||||
Destroy(preview.GetComponent<NetworkObject>());
|
||||
@@ -588,30 +587,41 @@ namespace Northbound
|
||||
|
||||
private void ExecuteDragBuild()
|
||||
{
|
||||
if (dragBuildingPositions.Count == 0)
|
||||
{
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 배치 가능한 건물이 없습니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
TowerData selectedData = BuildingManager.Instance.GetBuildableBuildings()[selectedBuildingIndex];
|
||||
|
||||
// Check affordability
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
if (coreResourceManager == null || !coreResourceManager.CanAfford(selectedData.mana * dragBuildingPositions.Count))
|
||||
// 드래그 위치가 없으면 현재 프리뷰 위치로 단일 건설 시도
|
||||
if (dragBuildingPositions.Count == 0)
|
||||
{
|
||||
if (previewObject != null && previewObject.activeSelf)
|
||||
{
|
||||
// 현재 프리뷰 위치에서 건설 시도
|
||||
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, maxPlacementDistance, groundLayer))
|
||||
{
|
||||
if (BuildingManager.Instance.IsValidPlacement(selectedData, hit.point, currentRotation, out Vector3 groundPosition))
|
||||
{
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
if (coreResourceManager == null || coreResourceManager.CanAfford(selectedData.mana))
|
||||
{
|
||||
BuildingManager.Instance.RequestPlaceFoundation(selectedBuildingIndex, groundPosition, currentRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check affordability
|
||||
var coreResourceManager2 = CoreResourceManager.Instance;
|
||||
if (coreResourceManager2 == null || !coreResourceManager2.CanAfford(selectedData.mana * dragBuildingPositions.Count))
|
||||
{
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 자원이 부족합니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
int successCount = 0;
|
||||
foreach (var position in dragBuildingPositions)
|
||||
{
|
||||
BuildingManager.Instance.RequestPlaceFoundation(selectedBuildingIndex, position, currentRotation);
|
||||
successCount++;
|
||||
}
|
||||
|
||||
Debug.Log($"<color=cyan>[BuildingPlacement] 드래그 건설 완료: {successCount}개의 {selectedData.buildingName} 배치 시도</color>");
|
||||
}
|
||||
|
||||
private void ClearDragPreviews()
|
||||
@@ -632,11 +642,7 @@ namespace Northbound
|
||||
if (!isBuildModeActive || previewObject == null) return;
|
||||
|
||||
// UI 위에서 클릭한 경우 무시
|
||||
if (IsPointerOverUI())
|
||||
{
|
||||
Debug.Log("<color=cyan>[BuildingPlacement] UI 위에서 클릭함 - 건설 취소</color>");
|
||||
return;
|
||||
}
|
||||
if (_isPointerOverUI) return;
|
||||
|
||||
// Get placement position
|
||||
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
||||
@@ -648,7 +654,6 @@ namespace Northbound
|
||||
var coreResourceManager = CoreResourceManager.Instance;
|
||||
if (coreResourceManager != null && !coreResourceManager.CanAfford(selectedData.mana))
|
||||
{
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 자원이 부족합니다.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -656,33 +661,37 @@ namespace Northbound
|
||||
{
|
||||
// 토대 배치 요청
|
||||
BuildingManager.Instance.RequestPlaceFoundation(selectedBuildingIndex, groundPosition, currentRotation);
|
||||
Debug.Log($"<color=cyan>[BuildingPlacement] 건설 시작: {selectedData.buildingName}</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("<color=yellow>[BuildingPlacement] 배치할 수 없는 위치입니다.</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 마우스 포인터가 UI 위에 있는지 확인
|
||||
/// 마우스 포인터가 건설 UI 위에 있는지 확인 (Update에서만 호출)
|
||||
/// </summary>
|
||||
private bool IsPointerOverUI()
|
||||
private bool CheckPointerOverUI()
|
||||
{
|
||||
// EventSystem이 없으면 UI 체크 불가능
|
||||
if (EventSystem.current == null)
|
||||
return false;
|
||||
|
||||
// New Input System을 사용하는 경우
|
||||
if (Mouse.current != null)
|
||||
if (Mouse.current == null)
|
||||
return false;
|
||||
|
||||
Vector2 mousePosition = Mouse.current.position.ReadValue();
|
||||
|
||||
// BuildingQuickslotUI의 패널이 마우스 아래에 있는지 확인
|
||||
if (BuildingQuickslotUI.Instance != null)
|
||||
{
|
||||
Vector2 mousePosition = Mouse.current.position.ReadValue();
|
||||
return EventSystem.current.IsPointerOverGameObject();
|
||||
var quickslotUI = BuildingQuickslotUI.Instance;
|
||||
|
||||
// quickslotPanel이 활성화되어 있고, 마우스가 그 위에 있으면 true
|
||||
if (quickslotUI.IsMouseOverQuickslot(mousePosition))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy Input System (폴백)
|
||||
return EventSystem.current.IsPointerOverGameObject();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -351,5 +351,20 @@ namespace Northbound
|
||||
{
|
||||
return slotButtons.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 마우스가 퀵슬롯 UI 위에 있는지 확인
|
||||
/// </summary>
|
||||
public bool IsMouseOverQuickslot(Vector2 mousePosition)
|
||||
{
|
||||
if (quickslotPanel == null || !quickslotPanel.activeSelf)
|
||||
return false;
|
||||
|
||||
RectTransform rectTransform = quickslotPanel.GetComponent<RectTransform>();
|
||||
if (rectTransform == null)
|
||||
return false;
|
||||
|
||||
return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, mousePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,20 @@ namespace Northbound
|
||||
mainCore.ConsumeResourceServerRpc(amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 자원을 환불 (건설 실패 시 등)
|
||||
/// </summary>
|
||||
public void AddResources(int amount)
|
||||
{
|
||||
if (mainCore == null)
|
||||
{
|
||||
Debug.LogWarning("메인 코어가 설정되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
mainCore.AddResource(amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 자원량 가져오기
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user