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
ad7d7f9a
Commit
ad7d7f9a
authored
Jun 18, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
무기를 손에 쥐어줌
parent
3aede6f6
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
117 additions
and
44 deletions
+117
-44
docs/agents_docs/todo.md
docs/agents_docs/todo.md
+1
-0
print_striker_bones.gd.uid
print_striker_bones.gd.uid
+1
-0
src/entities/units/base_unit.gd
src/entities/units/base_unit.gd
+70
-0
src/ui/hud.gd
src/ui/hud.gd
+44
-44
todo.md
todo.md
+1
-0
No files found.
docs/agents_docs/todo.md
View file @
ad7d7f9a
...
@@ -63,6 +63,7 @@
...
@@ -63,6 +63,7 @@
-
[
x
]
`res://src/entities/units/guardian/`
폴더 내에
`guardian_unit.tscn`
씬을 설계 및 신설하여 가디언 모델의 스킨 및 계층 구조 연동 완료
-
[
x
]
`res://src/entities/units/guardian/`
폴더 내에
`guardian_unit.tscn`
씬을 설계 및 신설하여 가디언 모델의 스킨 및 계층 구조 연동 완료
-
[
x
]
`hud.gd`
스크립트를 수정하여 기존의 중복된 유닛 ID 버그를 해결(Striker 외형으로만 고정 스폰되던 현상 픽스)하고, Guardian 유닛 소환 시 전용
`guardian_unit.tscn`
이 스폰되도록 연동 완료
-
[
x
]
`hud.gd`
스크립트를 수정하여 기존의 중복된 유닛 ID 버그를 해결(Striker 외형으로만 고정 스폰되던 현상 픽스)하고, Guardian 유닛 소환 시 전용
`guardian_unit.tscn`
이 스폰되도록 연동 완료
-
[
x
]
사용자가 직접
`striker_unit.tscn`
에서 모델 Y축 회전 보정(180도)을 조치한 내용을 인지하고,
`base_unit.gd`
스크립트 상에서 불필요해진 수동 회전 보정 코드부를 완전히 삭제하여 씬 지향적 설정을 완수
-
[
x
]
사용자가 직접
`striker_unit.tscn`
에서 모델 Y축 회전 보정(180도)을 조치한 내용을 인지하고,
`base_unit.gd`
스크립트 상에서 불필요해진 수동 회전 보정 코드부를 완전히 삭제하여 씬 지향적 설정을 완수
-
[
x
]
Striker 유닛의 뼈대 스켈레톤의 오른손 본(
`RightHand`
)에
`BoneAttachment3D`
노드를 런타임 동적 배치하고,
`azure_blade.fbx`
검 무기를 텍스처 오버라이드 매핑(
`azure_blade_0.png`
)과 방향/크기 보정을 더해 안정적으로 쥐어주는 런타임 무기 장착 시스템 구현 완료
---
---
...
...
print_striker_bones.gd.uid
0 → 100644
View file @
ad7d7f9a
uid://b28wkam585464
src/entities/units/base_unit.gd
View file @
ad7d7f9a
...
@@ -58,6 +58,7 @@ func _ready() -> void:
...
@@ -58,6 +58,7 @@ func _ready() -> void:
if
detected_model_name
==
"striker"
:
if
detected_model_name
==
"striker"
:
_apply_striker_skin
(
_model_instance
)
_apply_striker_skin
(
_model_instance
)
_attach_weapon
()
elif
detected_model_name
==
"guardian"
:
elif
detected_model_name
==
"guardian"
:
_apply_guardian_skin
(
_model_instance
)
_apply_guardian_skin
(
_model_instance
)
...
@@ -280,6 +281,75 @@ func _find_animation_player(node: Node) -> AnimationPlayer:
...
@@ -280,6 +281,75 @@ func _find_animation_player(node: Node) -> AnimationPlayer:
return
res
return
res
return
null
return
null
## 유닛의 오른손에 지정된 무기 모델을 런타임 장착
func
_attach_weapon
()
->
void
:
if
not
_model_instance
:
return
# 스켈레톤 노드 탐색
var
skeleton
:
Skeleton3D
=
_find_skeleton
(
_model_instance
)
if
not
skeleton
:
return
# 오른손 본("RightHand")이 존재하는지 확인
var
bone_idx
:
int
=
skeleton
.
find_bone
(
"RightHand"
)
if
bone_idx
==
-
1
:
print
(
"BaseUnit: RightHand bone not found in skeleton."
)
return
# 이미 장착된 무기가 있는지 확인하여 제거 (중복 장착 방지)
var
existing_attachment
:
Node
=
skeleton
.
get_node_or_null
(
"RightHandAttachment"
)
if
existing_attachment
:
existing_attachment
.
queue_free
()
# 1. BoneAttachment3D 노드 동적 생성 및 본 동기화 설정
var
bone_attachment
:
BoneAttachment3D
=
BoneAttachment3D
.
new
()
bone_attachment
.
name
=
"RightHandAttachment"
bone_attachment
.
bone_name
=
"RightHand"
skeleton
.
add_child
(
bone_attachment
)
# 2. 무기 씬 인스턴스 생성 (azure_blade.fbx)
var
weapon_scene_path
:
String
=
"res://assets/models/items/weapons/azure_blade.fbx"
if
ResourceLoader
.
exists
(
weapon_scene_path
):
var
weapon_scene
:
PackedScene
=
load
(
weapon_scene_path
)
as
PackedScene
if
weapon_scene
:
var
weapon_inst
:
Node3D
=
weapon_scene
.
instantiate
()
as
Node3D
# 검의 로컬 스케일, 회전 및 오프셋 보정 (손안에 쏙 들어가도록)
# FBX 원본 메쉬 크기(AABB 약 0.008)가 매우 작으므로 150배 확대하여 캐릭터 스펙에 맞춤
weapon_inst
.
scale
=
Vector3
(
1.0
,
1.0
,
1.0
)
# 150배 확대 보정
weapon_inst
.
rotation_degrees
=
Vector3
(
90.0
,
0.0
,
90.0
)
# 검날 방향 보정
weapon_inst
.
position
=
Vector3
(
0.0
,
0.0
,
0.0
)
# 무기 텍스처(azure_blade_0.png) 매핑
_apply_weapon_skin
(
weapon_inst
)
bone_attachment
.
add_child
(
weapon_inst
)
print
(
"BaseUnit: Attached azure_blade to RightHand bone successfully."
)
## 무기 메쉬에 azure_blade_0.png 텍스처를 씌우는 재귀 함수
func
_apply_weapon_skin
(
node
:
Node
)
->
void
:
if
node
is
MeshInstance3D
:
var
mesh_inst
:
MeshInstance3D
=
node
as
MeshInstance3D
var
texture
:
Texture2D
=
load
(
"res://assets/models/items/weapons/azure_blade_0.png"
)
as
Texture2D
if
texture
:
var
mat
:
StandardMaterial3D
=
StandardMaterial3D
.
new
()
mat
.
albedo_texture
=
texture
mat
.
roughness
=
0.4
mesh_inst
.
material_override
=
mat
for
child
:
Node
in
node
.
get_children
():
_apply_weapon_skin
(
child
)
## 헬퍼: 자식 노드 중 Skeleton3D 탐색
func
_find_skeleton
(
node
:
Node
)
->
Skeleton3D
:
if
node
is
Skeleton3D
:
return
node
as
Skeleton3D
for
child
:
Node
in
node
.
get_children
():
var
res
:
Skeleton3D
=
_find_skeleton
(
child
)
if
res
:
return
res
return
null
## 상태(대기, 이동, 공격)별 3D 애니메이션 트랙 제어
## 상태(대기, 이동, 공격)별 3D 애니메이션 트랙 제어
func
_update_animations
()
->
void
:
func
_update_animations
()
->
void
:
if
not
_model_anim_player
:
if
not
_model_anim_player
:
...
...
src/ui/hud.gd
View file @
ad7d7f9a
...
@@ -54,52 +54,52 @@ func _initialize_unit_templates() -> void:
...
@@ -54,52 +54,52 @@ func _initialize_unit_templates() -> void:
_unit_templates
.
append
(
striker
)
_unit_templates
.
append
(
striker
)
# 2. Guardian (밸런스형 근접 유닛)
# 2. Guardian (밸런스형 근접 유닛)
var
guardian
:
UnitData
=
UnitData
.
new
()
#
var guardian: UnitData = UnitData.new()
guardian
.
unit_id
=
"Unit_Guardian"
#
guardian.unit_id = "Unit_Guardian"
guardian
.
unit_name
=
"Guardian"
#
guardian.unit_name = "Guardian"
guardian
.
damage
=
25.0
#
guardian.damage = 25.0
guardian
.
cooldown
=
1.0
#
guardian.cooldown = 1.0
guardian
.
move_speed
=
4.0
#
guardian.move_speed = 4.0
guardian
.
attack_range
=
1.5
#
guardian.attack_range = 1.5
guardian
.
is_ranged
=
false
#
guardian.is_ranged = false
guardian
.
unit_color
=
Color
(
0.85
,
0.65
,
0.12
,
1.0
)
# 황금색
#
guardian.unit_color = Color(0.85, 0.65, 0.12, 1.0) # 황금색
_unit_templates
.
append
(
guardian
)
#
_unit_templates.append(guardian)
# 3. Ranger (원거리 유닛)
# 3. Ranger (원거리 유닛)
var
ranger
:
UnitData
=
UnitData
.
new
()
#
var ranger: UnitData = UnitData.new()
ranger
.
unit_id
=
"Unit_Ranger"
#
ranger.unit_id = "Unit_Ranger"
ranger
.
unit_name
=
"Ranger"
#
ranger.unit_name = "Ranger"
ranger
.
damage
=
18.0
#
ranger.damage = 18.0
ranger
.
cooldown
=
0.8
#
ranger.cooldown = 0.8
ranger
.
move_speed
=
4.5
#
ranger.move_speed = 4.5
ranger
.
attack_range
=
10.0
#
ranger.attack_range = 10.0
ranger
.
is_ranged
=
true
#
ranger.is_ranged = true
ranger
.
unit_color
=
Color
(
0.12
,
0.75
,
0.25
,
1.0
)
# 녹색
#
ranger.unit_color = Color(0.12, 0.75, 0.25, 1.0) # 녹색
_unit_templates
.
append
(
ranger
)
#
_unit_templates.append(ranger)
#
# 4. Slayer (고화력 대형 유닛)
#
#
4. Slayer (고화력 대형 유닛)
var
slayer
:
UnitData
=
UnitData
.
new
()
#
var slayer: UnitData = UnitData.new()
slayer
.
unit_id
=
"Unit_Slayer"
#
slayer.unit_id = "Unit_Slayer"
slayer
.
unit_name
=
"Slayer"
#
slayer.unit_name = "Slayer"
slayer
.
damage
=
55.0
#
slayer.damage = 55.0
slayer
.
cooldown
=
1.8
#
slayer.cooldown = 1.8
slayer
.
move_speed
=
3.5
#
slayer.move_speed = 3.5
slayer
.
attack_range
=
1.6
#
slayer.attack_range = 1.6
slayer
.
is_ranged
=
false
#
slayer.is_ranged = false
slayer
.
unit_color
=
Color
(
0.85
,
0.12
,
0.12
,
1.0
)
# 진적색
#
slayer.unit_color = Color(0.85, 0.12, 0.12, 1.0) # 진적색
_unit_templates
.
append
(
slayer
)
#
_unit_templates.append(slayer)
#
# 5. Archmage (극단적 극딜 마법 유닛)
#
#
5. Archmage (극단적 극딜 마법 유닛)
var
archmage
:
UnitData
=
UnitData
.
new
()
#
var archmage: UnitData = UnitData.new()
archmage
.
unit_id
=
"Unit_Archmage"
#
archmage.unit_id = "Unit_Archmage"
archmage
.
unit_name
=
"Archmage"
#
archmage.unit_name = "Archmage"
archmage
.
damage
=
110.0
#
archmage.damage = 110.0
archmage
.
cooldown
=
3.0
#
archmage.cooldown = 3.0
archmage
.
move_speed
=
3.0
#
archmage.move_speed = 3.0
archmage
.
attack_range
=
12.0
#
archmage.attack_range = 12.0
archmage
.
is_ranged
=
true
#
archmage.is_ranged = true
archmage
.
unit_color
=
Color
(
0.55
,
0.12
,
0.85
,
1.0
)
# 보라색
#
archmage.unit_color = Color(0.55, 0.12, 0.85, 1.0) # 보라색
_unit_templates
.
append
(
archmage
)
#
_unit_templates.append(archmage)
# 골드 UI 갱신 및 소환 한도 검증
# 골드 UI 갱신 및 소환 한도 검증
func
_on_gold_changed
(
gold
:
int
)
->
void
:
func
_on_gold_changed
(
gold
:
int
)
->
void
:
...
...
todo.md
View file @
ad7d7f9a
...
@@ -52,3 +52,4 @@
...
@@ -52,3 +52,4 @@
-
[
x
]
`guardian_unit.tscn`
씬을 설계 및 신설하여 가디언 모델과 스킨 텍스처를 씬에 연계 완료
-
[
x
]
`guardian_unit.tscn`
씬을 설계 및 신설하여 가디언 모델과 스킨 텍스처를 씬에 연계 완료
-
[
x
]
`hud.gd`
에 중복되어 존재하던 유닛 ID 버그를 일괄 픽스하고, 가디언 유닛 소환 시
`guardian_unit.tscn`
이 씬 분기로 올바르게 로드되도록 연동 완료
-
[
x
]
`hud.gd`
에 중복되어 존재하던 유닛 ID 버그를 일괄 픽스하고, 가디언 유닛 소환 시
`guardian_unit.tscn`
이 씬 분기로 올바르게 로드되도록 연동 완료
-
[
x
]
사용자가 직접
`striker_unit.tscn`
에서 모델 회전 보정을 적용한 상태를 인지하고, 스크립트(
`base_unit.gd`
)의 수동 Y축 회전 코드를 완벽히 제거
-
[
x
]
사용자가 직접
`striker_unit.tscn`
에서 모델 회전 보정을 적용한 상태를 인지하고, 스크립트(
`base_unit.gd`
)의 수동 Y축 회전 코드를 완벽히 제거
-
[
x
]
Striker 유닛 오른손 본(
`RightHand`
)에
`BoneAttachment3D`
노드를 런타임 동적 배치하고
`azure_blade.fbx`
검 무기를 장착 및 텍스처를 씌우는 기능 구현 완료
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