Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
L
ldefense
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Packages
Packages
Container Registry
Analytics
CI / CD Analytics
Repository Analytics
Value Stream Analytics
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gavin An
ldefense
Commits
d8eba5c2
Commit
d8eba5c2
authored
Jul 27, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
작업중
parent
24121fe1
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
363 additions
and
20 deletions
+363
-20
src/core/unit_controller.gd
src/core/unit_controller.gd
+328
-18
src/entities/units/base/base_unit.gd
src/entities/units/base/base_unit.gd
+28
-0
src/ui/unit_placement/hud_unit_placement.gd
src/ui/unit_placement/hud_unit_placement.gd
+7
-2
No files found.
src/core/unit_controller.gd
View file @
d8eba5c2
This diff is collapsed.
Click to expand it.
src/entities/units/base/base_unit.gd
View file @
d8eba5c2
...
@@ -12,6 +12,9 @@ const INVALID_PLACEMENT_CELL: Vector3i = Vector3i(2147483647, 2147483647, 214748
...
@@ -12,6 +12,9 @@ const INVALID_PLACEMENT_CELL: Vector3i = Vector3i(2147483647, 2147483647, 214748
var
is_selected
:
bool
=
false
var
is_selected
:
bool
=
false
var
is_tile_bound
:
bool
=
false
var
is_tile_bound
:
bool
=
false
var
occupied_tile_cell
:
Vector3i
=
INVALID_PLACEMENT_CELL
var
occupied_tile_cell
:
Vector3i
=
INVALID_PLACEMENT_CELL
var
_has_pending_tile_rebind
:
bool
=
false
var
_pending_tile_center
:
Vector3
=
Vector3
.
ZERO
var
_pending_tile_cell
:
Vector3i
=
INVALID_PLACEMENT_CELL
# 전투 관련 상태
# 전투 관련 상태
var
_target_monster
:
Node3D
=
null
var
_target_monster
:
Node3D
=
null
...
@@ -95,6 +98,8 @@ func _physics_process(delta: float) -> void:
...
@@ -95,6 +98,8 @@ func _physics_process(delta: float) -> void:
if
_is_moving
and
_has_reached_manual_move_target
():
if
_is_moving
and
_has_reached_manual_move_target
():
_is_moving
=
false
_is_moving
=
false
if
_has_pending_tile_rebind
:
_complete_pending_tile_rebind
()
# 2. 적 자동 탐색 (타겟이 없고 수동 강제 이동 방지 쿨다운이 완료, 공격 쿨다운이 끝난 경우)
# 2. 적 자동 탐색 (타겟이 없고 수동 강제 이동 방지 쿨다운이 완료, 공격 쿨다운이 끝난 경우)
if
not
_is_moving
and
not
_target_monster
and
_auto_target_cooldown
<=
0.0
and
_attack_lock_timer
<=
0.0
:
if
not
_is_moving
and
not
_target_monster
and
_auto_target_cooldown
<=
0.0
and
_attack_lock_timer
<=
0.0
:
...
@@ -336,6 +341,9 @@ func hold_position() -> void:
...
@@ -336,6 +341,9 @@ func hold_position() -> void:
func
place_on_tile
(
tile_center
:
Vector3
,
tile_cell
:
Vector3i
)
->
void
:
func
place_on_tile
(
tile_center
:
Vector3
,
tile_cell
:
Vector3i
)
->
void
:
is_tile_bound
=
true
is_tile_bound
=
true
occupied_tile_cell
=
tile_cell
occupied_tile_cell
=
tile_cell
_has_pending_tile_rebind
=
false
_pending_tile_center
=
Vector3
.
ZERO
_pending_tile_cell
=
INVALID_PLACEMENT_CELL
_is_holding
=
true
_is_holding
=
true
_is_moving
=
false
_is_moving
=
false
_target_monster
=
null
_target_monster
=
null
...
@@ -348,6 +356,17 @@ func place_on_tile(tile_center: Vector3, tile_cell: Vector3i) -> void:
...
@@ -348,6 +356,17 @@ func place_on_tile(tile_center: Vector3, tile_cell: Vector3i) -> void:
_nav_agent
.
target_position
=
tile_center
_nav_agent
.
target_position
=
tile_center
velocity
=
Vector3
.
ZERO
velocity
=
Vector3
.
ZERO
## 타일에 고정된 유닛을 다른 배치 가능 타일로 이동시킵니다.
## 일반 move_to()는 타일 고정 유닛을 움직이지 않게 막으므로, 유닛 재배치 버튼 전용 경로를 따로 둡니다.
## 이동 중에는 현재 타일 점유를 해제하고, 목적지에 도착하면 place_on_tile()을 다시 호출해 새 타일에 고정합니다.
func
move_to_tile
(
tile_center
:
Vector3
,
tile_cell
:
Vector3i
)
->
void
:
_has_pending_tile_rebind
=
true
_pending_tile_center
=
tile_center
_pending_tile_cell
=
tile_cell
is_tile_bound
=
false
occupied_tile_cell
=
INVALID_PLACEMENT_CELL
_apply_move_command
(
tile_center
)
## 외부에서 호출하는 수동 이동 명령
## 외부에서 호출하는 수동 이동 명령
func
move_to
(
target_pos
:
Vector3
)
->
void
:
func
move_to
(
target_pos
:
Vector3
)
->
void
:
if
is_tile_bound
:
if
is_tile_bound
:
...
@@ -382,6 +401,15 @@ func _apply_move_command(target_pos: Vector3) -> void:
...
@@ -382,6 +401,15 @@ func _apply_move_command(target_pos: Vector3) -> void:
_auto_target_cooldown
=
0.5
# 수동 강제 이동 시 0.5초 동안 자동 공격 타겟 지정을 비활성화하여 피신을 허용
_auto_target_cooldown
=
0.5
# 수동 강제 이동 시 0.5초 동안 자동 공격 타겟 지정을 비활성화하여 피신을 허용
_nav_agent
.
target_position
=
target_pos
_nav_agent
.
target_position
=
target_pos
## move_to_tile()로 시작한 재배치 이동이 끝났을 때 새 타일에 유닛을 고정합니다.
## NavigationAgent 도착 판정은 약간의 허용 거리를 갖기 때문에, 마지막에는 타일 중심으로 스냅해 배치 그리드와 정확히 맞춥니다.
func
_complete_pending_tile_rebind
()
->
void
:
if
_pending_tile_cell
==
INVALID_PLACEMENT_CELL
:
_has_pending_tile_rebind
=
false
return
place_on_tile
(
_pending_tile_center
,
_pending_tile_cell
)
## 근접 공격의 타격 확정 전 구간인지 확인합니다.
## 근접 공격의 타격 확정 전 구간인지 확인합니다.
## - 원거리 유닛은 공격 모션 타이머가 있어도 이동 가능해야 하므로 false를 반환합니다.
## - 원거리 유닛은 공격 모션 타이머가 있어도 이동 가능해야 하므로 false를 반환합니다.
func
_is_melee_attack_locked
()
->
bool
:
func
_is_melee_attack_locked
()
->
bool
:
...
...
src/ui/unit_placement/hud_unit_placement.gd
View file @
d8eba5c2
...
@@ -12,6 +12,11 @@ const MAGE_SCENE: PackedScene = preload("res://src/entities/units/mage/mage_unit
...
@@ -12,6 +12,11 @@ const MAGE_SCENE: PackedScene = preload("res://src/entities/units/mage/mage_unit
const
WARRIOR_LV1_SCENE
:
PackedScene
=
preload
(
"res://src/entities/units/warrior/lv1/warrior_unit.tscn"
)
const
WARRIOR_LV1_SCENE
:
PackedScene
=
preload
(
"res://src/entities/units/warrior/lv1/warrior_unit.tscn"
)
const
PLACEMENT_TILE_OVERLAY_SCENE
:
PackedScene
=
preload
(
"res://src/ui/unit_placement/placement_tile_overlay.tscn"
)
const
PLACEMENT_TILE_OVERLAY_SCENE
:
PackedScene
=
preload
(
"res://src/ui/unit_placement/placement_tile_overlay.tscn"
)
const
OVERLAY_POOL_WARMUP_BATCH_SIZE
:
int
=
16
const
OVERLAY_POOL_WARMUP_BATCH_SIZE
:
int
=
16
## MonsterPath와 가까운 타일을 "몬스터 길"로 판정할 때 추가로 더해 주는 여유 폭입니다.
## 실제 판정 거리는 `타일 반폭 + 타일 크기 * 이 비율`입니다.
## 예를 들어 GridMap 셀 크기가 2m이고 값이 0.15라면, 타일 중심이 Path3D에서 1.3m 이내일 때 길 타일로 취급합니다.
## Path3D가 타일 정중앙을 지나지 않거나 모델/그리드가 조금 어긋나도 몬스터 길에 유닛이 배치되지 않게 막는 안전 마진입니다.
const
MONSTER_PATH_TILE_EXTRA_MARGIN_RATIO
:
float
=
0.15
const
MONSTER_PATH_TILE_EXTRA_MARGIN_RATIO
:
float
=
0.15
var
_hud
:
Control
=
null
var
_hud
:
Control
=
null
...
@@ -276,7 +281,6 @@ func _get_tile_info_from_screen(screen_pos: Vector2) -> Dictionary:
...
@@ -276,7 +281,6 @@ func _get_tile_info_from_screen(screen_pos: Vector2) -> Dictionary:
return
{}
return
{}
var
tile_center
:
Vector3
=
grid_map
.
to_global
(
grid_map
.
map_to_local
(
tile_cell
))
var
tile_center
:
Vector3
=
grid_map
.
to_global
(
grid_map
.
map_to_local
(
tile_cell
))
tile_center
.
y
+=
1.0
return
{
return
{
"cell"
:
tile_cell
,
"cell"
:
tile_cell
,
"center"
:
tile_center
"center"
:
tile_center
...
@@ -406,7 +410,8 @@ func _is_cell_close_to_monster_path(grid_map: GridMap, monster_path: Path3D, til
...
@@ -406,7 +410,8 @@ func _is_cell_close_to_monster_path(grid_map: GridMap, monster_path: Path3D, til
var
closest_world_point
:
Vector3
=
monster_path
.
to_global
(
closest_local_point
)
var
closest_world_point
:
Vector3
=
monster_path
.
to_global
(
closest_local_point
)
# 배치 판정은 바닥 평면 기준이므로 y 높이 차이는 무시합니다.
# 배치 판정은 바닥 평면 기준이므로 y 높이 차이는 무시합니다.
# half_tile_width에 작은 여유를 더해 경로가 타일 중앙에서 조금 벗어나 있어도 해당 길 타일이 잠기도록 합니다.
# half_tile_width는 타일 중심에서 타일 가장자리까지의 거리이고,
# path_margin은 MonsterPath가 타일 중앙선에서 조금 벗어난 경우까지 길 타일로 묶기 위한 추가 여유입니다.
tile_center
.
y
=
0.0
tile_center
.
y
=
0.0
closest_world_point
.
y
=
0.0
closest_world_point
.
y
=
0.0
var
half_tile_width
:
float
=
maxf
(
grid_map
.
cell_size
.
x
,
grid_map
.
cell_size
.
z
)
*
0.5
var
half_tile_width
:
float
=
maxf
(
grid_map
.
cell_size
.
x
,
grid_map
.
cell_size
.
z
)
*
0.5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment