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
57468de7
Commit
57468de7
authored
Jul 01, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
작업중
parent
36a467ae
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
53 additions
and
7 deletions
+53
-7
src/entities/units/base_unit.gd
src/entities/units/base_unit.gd
+49
-4
src/entities/units/hero/base_hero.gd
src/entities/units/hero/base_hero.gd
+0
-0
src/entities/units/hero/base_hero.gd.uid
src/entities/units/hero/base_hero.gd.uid
+0
-0
src/entities/units/hero/dwarf/dwarf.tscn
src/entities/units/hero/dwarf/dwarf.tscn
+0
-0
src/entities/units/hero/dwarf/dwarf_hero.gd
src/entities/units/hero/dwarf/dwarf_hero.gd
+1
-0
src/entities/units/hero/dwarf/dwarf_hero.gd.uid
src/entities/units/hero/dwarf/dwarf_hero.gd.uid
+0
-0
src/entities/units/hero/dwarf/dwarf_hero.tscn
src/entities/units/hero/dwarf/dwarf_hero.tscn
+2
-2
src/ui/hud.gd
src/ui/hud.gd
+1
-1
No files found.
src/entities/units/base_unit.gd
View file @
57468de7
...
@@ -2,6 +2,7 @@ class_name BaseUnit
...
@@ -2,6 +2,7 @@ class_name BaseUnit
extends
CharacterBody3D
extends
CharacterBody3D
const
UnitHelper
=
preload
(
"res://src/entities/units/unit_helper.gd"
)
const
UnitHelper
=
preload
(
"res://src/entities/units/unit_helper.gd"
)
const
MELEE_HIT_CONFIRM_PADDING
:
float
=
0.05
## 플레이어 유닛 기본 클래스 (RTS 식 이동, 몬스터 자동 감지 및 공격 수행)
## 플레이어 유닛 기본 클래스 (RTS 식 이동, 몬스터 자동 감지 및 공격 수행)
...
@@ -31,7 +32,10 @@ var _model_instance: Node3D = null
...
@@ -31,7 +32,10 @@ var _model_instance: Node3D = null
var
_model_anim_player
:
AnimationPlayer
=
null
var
_model_anim_player
:
AnimationPlayer
=
null
var
_last_anim_state
:
String
=
""
var
_last_anim_state
:
String
=
""
var
_is_currently_attacking
:
bool
=
false
var
_is_currently_attacking
:
bool
=
false
var
_attack_lock_timer
:
float
=
0.0
# 공격 모션 완주 및 물리 이동 차단을 위한 타이머
var
_attack_lock_timer
:
float
=
0.0
# 공격 모션 재생 시간을 추적하는 타이머입니다.
var
_melee_move_lock_timer
:
float
=
0.0
# 근접 공격의 타격 확정 전까지만 이동을 막는 별도 타이머입니다.
var
_has_queued_move_after_attack
:
bool
=
false
var
_queued_move_position
:
Vector3
=
Vector3
.
ZERO
var
attack_speed_mult
:
float
=
1.0
# 소환사 주문(가속) 등으로 변경 가능한 공속 배율
var
attack_speed_mult
:
float
=
1.0
# 소환사 주문(가속) 등으로 변경 가능한 공속 배율
func
_ready
()
->
void
:
func
_ready
()
->
void
:
...
@@ -64,6 +68,10 @@ func _physics_process(delta: float) -> void:
...
@@ -64,6 +68,10 @@ func _physics_process(delta: float) -> void:
_attack_timer
-=
delta
*
attack_speed_mult
_attack_timer
-=
delta
*
attack_speed_mult
if
_attack_lock_timer
>
0.0
:
if
_attack_lock_timer
>
0.0
:
_attack_lock_timer
-=
delta
*
attack_speed_mult
_attack_lock_timer
-=
delta
*
attack_speed_mult
if
_melee_move_lock_timer
>
0.0
:
_melee_move_lock_timer
-=
delta
*
attack_speed_mult
if
_melee_move_lock_timer
<=
0.0
and
_has_queued_move_after_attack
:
_apply_move_command
(
_queued_move_position
)
if
_auto_target_cooldown
>
0.0
:
if
_auto_target_cooldown
>
0.0
:
_auto_target_cooldown
-=
delta
_auto_target_cooldown
-=
delta
...
@@ -108,10 +116,12 @@ func _process_attack_logic(_delta: float) -> void:
...
@@ -108,10 +116,12 @@ func _process_attack_logic(_delta: float) -> void:
if
not
_target_monster
:
if
not
_target_monster
:
_is_currently_attacking
=
false
_is_currently_attacking
=
false
_attack_lock_timer
=
0.0
_attack_lock_timer
=
0.0
_melee_move_lock_timer
=
0.0
return
return
# 공격 모션 재생 중(공격 잠금 시간 동안)에는 무조건 이동하지 않고 멈춰서 공격 모션 유지
# 근접 유닛은 타격이 확정되기 전까지만 제자리에 고정합니다.
if
_attack_lock_timer
>
0.0
:
# 타격 판정 이후의 후딜 구간은 이동 명령으로 빠져나갈 수 있게 두어 웨이브에 갇히는 상황을 줄입니다.
if
_is_melee_attack_locked
():
_is_currently_attacking
=
true
_is_currently_attacking
=
true
velocity
.
x
=
0.0
velocity
.
x
=
0.0
velocity
.
z
=
0.0
velocity
.
z
=
0.0
...
@@ -262,6 +272,7 @@ func _try_attack() -> void:
...
@@ -262,6 +272,7 @@ func _try_attack() -> void:
var
target_ref
:
Node3D
=
_target_monster
var
target_ref
:
Node3D
=
_target_monster
var
damage_amount
:
float
=
unit_data
.
damage
var
damage_amount
:
float
=
unit_data
.
damage
var
damage_delay
:
float
=
_attack_lock_timer
*
0.5
var
damage_delay
:
float
=
_attack_lock_timer
*
0.5
_set_melee_move_lock_until_hit
(
damage_delay
)
if
damage_delay
>
0.0
:
if
damage_delay
>
0.0
:
get_tree
()
.
create_timer
(
damage_delay
)
.
timeout
.
connect
(
get_tree
()
.
create_timer
(
damage_delay
)
.
timeout
.
connect
(
...
@@ -286,21 +297,55 @@ func _show_attack_visual() -> void:
...
@@ -286,21 +297,55 @@ func _show_attack_visual() -> void:
func
hold_position
()
->
void
:
func
hold_position
()
->
void
:
_is_holding
=
true
_is_holding
=
true
_target_monster
=
null
_target_monster
=
null
_has_queued_move_after_attack
=
false
_nav_agent
.
target_position
=
global_position
_nav_agent
.
target_position
=
global_position
velocity
=
Vector3
.
ZERO
velocity
=
Vector3
.
ZERO
## 외부에서 호출하는 수동 이동 명령
## 외부에서 호출하는 수동 이동 명령
func
move_to
(
target_pos
:
Vector3
)
->
void
:
func
move_to
(
target_pos
:
Vector3
)
->
void
:
# 근접 유닛은 타격 확정 전 이동 명령을 잠시 보관했다가, 판정 직후 바로 이동합니다.
# 원거리 유닛이나 근접 후딜 구간은 즉시 공격을 끊고 이동해 조작 반응성을 유지합니다.
if
_is_melee_attack_locked
():
_has_queued_move_after_attack
=
true
_queued_move_position
=
target_pos
velocity
.
x
=
0.0
velocity
.
z
=
0.0
if
_target_monster
and
is_instance_valid
(
_target_monster
):
_look_at_target
(
_target_monster
.
global_position
)
return
_apply_move_command
(
target_pos
)
## 실제 수동 이동 상태 전환을 한곳에서 처리합니다.
## - 근접 공격의 후딜 캔슬과 원거리 카이팅 모두 이 경로를 공유합니다.
func
_apply_move_command
(
target_pos
:
Vector3
)
->
void
:
_is_holding
=
false
# 수동 조작 시 홀드 해제
_is_holding
=
false
# 수동 조작 시 홀드 해제
_target_monster
=
null
# 이동 명령 시 강제 공격 해제
_target_monster
=
null
# 이동 명령 시 강제 공격 해제
_attack_lock_timer
=
0.0
# 공격 애니메이션 진행 중이더라도 강제 이동 명령 시 즉시 캔슬하고 이동 (스타크래프트 식 무빙 캔슬)
_attack_lock_timer
=
0.0
# 타격 확정 이후의 후딜 또는 원거리 공격 모션은 이동 명령으로 캔슬합니다.
_melee_move_lock_timer
=
0.0
_is_currently_attacking
=
false
_is_currently_attacking
=
false
_has_queued_move_after_attack
=
false
_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
## 근접 공격의 타격 확정 전 구간인지 확인합니다.
## - 원거리 유닛은 공격 모션 타이머가 있어도 이동 가능해야 하므로 false를 반환합니다.
func
_is_melee_attack_locked
()
->
bool
:
return
unit_data
!=
null
and
not
unit_data
.
is_ranged
and
_melee_move_lock_timer
>
0.0
## 근접 공격 판정이 확정되기 전까지만 이동을 막습니다.
## - 아주 짧은 패딩을 더해 데미지 타이머 신호가 먼저 처리될 여유를 둡니다.
func
_set_melee_move_lock_until_hit
(
damage_delay
:
float
)
->
void
:
if
unit_data
==
null
or
unit_data
.
is_ranged
:
_melee_move_lock_timer
=
0.0
return
_melee_move_lock_timer
=
maxf
(
0.0
,
damage_delay
+
MELEE_HIT_CONFIRM_PADDING
)
## 외부에서 호출하는 특정 몬스터 강제 공격 지정
## 외부에서 호출하는 특정 몬스터 강제 공격 지정
func
attack_target
(
monster
:
Node3D
)
->
void
:
func
attack_target
(
monster
:
Node3D
)
->
void
:
_is_holding
=
false
# 강제 공격 시 홀드 해제
_is_holding
=
false
# 강제 공격 시 홀드 해제
_has_queued_move_after_attack
=
false
if
is_instance_valid
(
monster
)
and
not
monster
.
get
(
"is_dead"
):
if
is_instance_valid
(
monster
)
and
not
monster
.
get
(
"is_dead"
):
_target_monster
=
monster
_target_monster
=
monster
_nav_agent
.
target_position
=
monster
.
global_position
_nav_agent
.
target_position
=
monster
.
global_position
...
...
src/entities/hero/base_hero.gd
→
src/entities/
units/
hero/base_hero.gd
View file @
57468de7
File moved
src/entities/hero/base_hero.gd.uid
→
src/entities/
units/
hero/base_hero.gd.uid
View file @
57468de7
File moved
src/entities/hero/dwarf/dwarf.tscn
→
src/entities/
units/
hero/dwarf/dwarf.tscn
View file @
57468de7
File moved
src/entities/hero/dwarf/dwarf_hero.gd
→
src/entities/
units/
hero/dwarf/dwarf_hero.gd
View file @
57468de7
...
@@ -58,6 +58,7 @@ func _try_attack() -> void:
...
@@ -58,6 +58,7 @@ func _try_attack() -> void:
var
target_ref
:
Node3D
=
_target_monster
var
target_ref
:
Node3D
=
_target_monster
var
damage_amount
:
float
=
unit_data
.
damage
var
damage_amount
:
float
=
unit_data
.
damage
var
damage_delay
:
float
=
_attack_lock_timer
*
DWARF_ATTACK_DAMAGE_RATIO
var
damage_delay
:
float
=
_attack_lock_timer
*
DWARF_ATTACK_DAMAGE_RATIO
_set_melee_move_lock_until_hit
(
damage_delay
)
# 도끼가 몸 앞쪽으로 떨어지는 구간에 데미지가 들어가도록 지연시켜 시각적 타격감과 판정을 맞춥니다.
# 도끼가 몸 앞쪽으로 떨어지는 구간에 데미지가 들어가도록 지연시켜 시각적 타격감과 판정을 맞춥니다.
if
damage_delay
>
0.0
:
if
damage_delay
>
0.0
:
...
...
src/entities/hero/dwarf/dwarf_hero.gd.uid
→
src/entities/
units/
hero/dwarf/dwarf_hero.gd.uid
View file @
57468de7
File moved
src/entities/hero/dwarf/dwarf_hero.tscn
→
src/entities/
units/
hero/dwarf/dwarf_hero.tscn
View file @
57468de7
[gd_scene format=3 uid="uid://np5fiyv02pk"]
[gd_scene format=3 uid="uid://np5fiyv02pk"]
[ext_resource type="PackedScene" uid="uid://lswmiam1ftlw" path="res://src/entities/hero/dwarf/dwarf.tscn" id="1_b0qj8"]
[ext_resource type="PackedScene" uid="uid://lswmiam1ftlw" path="res://src/entities/
units/
hero/dwarf/dwarf.tscn" id="1_b0qj8"]
[ext_resource type="Script" uid="uid://dsckp7uaawijh" path="res://src/entities/hero/dwarf/dwarf_hero.gd" id="1_cthrw"]
[ext_resource type="Script" uid="uid://dsckp7uaawijh" path="res://src/entities/
units/
hero/dwarf/dwarf_hero.gd" id="1_cthrw"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_pe3j2"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_pe3j2"]
radius = 0.4
radius = 0.4
...
...
src/ui/hud.gd
View file @
57468de7
...
@@ -332,7 +332,7 @@ func _on_summon_hero_pressed() -> void:
...
@@ -332,7 +332,7 @@ func _on_summon_hero_pressed() -> void:
return
return
var
chosen_template
:
UnitData
=
DataManager
.
hero_templates
[
0
]
var
chosen_template
:
UnitData
=
DataManager
.
hero_templates
[
0
]
var
hero_scene
:
PackedScene
=
load
(
"res://src/entities/hero/dwarf/dwarf_hero.tscn"
)
as
PackedScene
var
hero_scene
:
PackedScene
=
load
(
"res://src/entities/
units/
hero/dwarf/dwarf_hero.tscn"
)
as
PackedScene
if
not
hero_scene
:
if
not
hero_scene
:
print
(
"HUD Error: Failed to load dwarf_hero.tscn!"
)
print
(
"HUD Error: Failed to load dwarf_hero.tscn!"
)
return
return
...
...
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