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
3410532f
Commit
3410532f
authored
Jun 19, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
근접유닛 애니매이션 관련 수정
parent
9939b856
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
279 additions
and
185 deletions
+279
-185
docs/agents.md
docs/agents.md
+1
-1
docs/idea/design.md
docs/idea/design.md
+1
-0
src/autoload/data_manager.gd
src/autoload/data_manager.gd
+1
-1
src/core/main.tscn
src/core/main.tscn
+1
-1
src/entities/monsters/base_monster.gd
src/entities/monsters/base_monster.gd
+2
-2
src/entities/units/base_unit.gd
src/entities/units/base_unit.gd
+140
-179
src/entities/units/unit_data.gd
src/entities/units/unit_data.gd
+0
-1
src/entities/units/unit_helper.gd
src/entities/units/unit_helper.gd
+132
-0
src/entities/units/unit_helper.gd.uid
src/entities/units/unit_helper.gd.uid
+1
-0
No files found.
docs/agents.md
View file @
3410532f
docs/idea/design.md
0 → 100644
View file @
3410532f
매 10 라운드마다 보스 출현
src/autoload/data_manager.gd
View file @
3410532f
...
...
@@ -15,7 +15,7 @@ func _initialize_unit_templates() -> void:
striker
.
unit_id
=
"Unit_Striker"
striker
.
unit_name
=
"Striker"
striker
.
damage
=
12.0
striker
.
cooldown
=
0
.5
striker
.
cooldown
=
1
.5
striker
.
move_speed
=
6.0
striker
.
attack_range
=
1.5
striker
.
is_ranged
=
false
...
...
src/core/main.tscn
View file @
3410532f
...
...
@@ -2,7 +2,7 @@
[ext_resource type="Script" uid="uid://dd1xgi6hnpuvs" path="res://src/core/rts_camera.gd" id="1_rts_cam"]
[ext_resource type="Script" uid="uid://cq7r51whh6po" path="res://src/core/stage_manager.gd" id="2_stage_mgr"]
[ext_resource type="PackedScene" path="res://src/entities/monsters/noble_man/noble_man_unit.tscn" id="3_base_monster"]
[ext_resource type="PackedScene"
uid="uid://dimlohck6ebg7"
path="res://src/entities/monsters/noble_man/noble_man_unit.tscn" id="3_base_monster"]
[ext_resource type="Script" uid="uid://dkplkt6q8e3b5" path="res://src/core/unit_controller.gd" id="4_unit_ctrl"]
[ext_resource type="PackedScene" uid="uid://bqga1rvcjyydy" path="res://src/ui/hud.tscn" id="5_hud"]
...
...
src/entities/monsters/base_monster.gd
View file @
3410532f
...
...
@@ -4,7 +4,7 @@ extends PathFollow3D
## 기본 몬스터 클래스 (Path3D 상하위에서 경로를 따라 회전하며 피격/사망 처리됨)
# 몬스터 능력치 설정
@
export
var
speed
:
float
=
6
.0
@
export
var
speed
:
float
=
2
.0
var
max_hp
:
float
=
100.0
var
current_hp
:
float
=
100.0
var
gold_reward
:
int
=
15
...
...
@@ -158,7 +158,7 @@ func _create_hp_bar() -> void:
# 3. Sprite3D 생성 (Viewport의 2D 렌더링 텍스처를 3D 공간에 띄움)
var
sprite
:
Sprite3D
=
Sprite3D
.
new
()
sprite
.
billboard
=
BaseMaterial3D
.
BILLBOARD_ENABLED
# 카메라를 항상 마주하도록 설정
sprite
.
position
=
Vector3
(
0.0
,
1.2
,
0.0
)
# 몬스터 머리 위
오프셋
sprite
.
position
=
Vector3
(
0.0
,
0.15
,
0.0
)
# 몬스터 발밑
오프셋
sprite
.
texture
=
viewport
.
get_texture
()
sprite
.
cast_shadow
=
GeometryInstance3D
.
SHADOW_CASTING_SETTING_OFF
# 그림자 연산 제외
sprite
.
no_depth_test
=
false
# 지형이나 다른 장막 뒤에 가려지도록 설정
...
...
src/entities/units/base_unit.gd
View file @
3410532f
This diff is collapsed.
Click to expand it.
src/entities/units/unit_data.gd
View file @
3410532f
...
...
@@ -2,7 +2,6 @@ class_name UnitData
extends
Resource
## 유닛의 기획 능력치를 정의하는 커스텀 리소스 (UnitData)
@
export
var
unit_id
:
String
=
""
@
export
var
unit_name
:
String
=
""
@
export
var
damage
:
float
=
10.0
...
...
src/entities/units/unit_helper.gd
0 → 100644
View file @
3410532f
class_name
UnitHelper
extends
Object
## 유닛 외형 렌더링 및 3D 장착 어태치먼트 제어를 위한 정적 유틸리티 헬퍼
## 자식 메쉬에 지정된 텍스처를 씌우는 재귀 함수
static
func
apply_skin
(
node
:
Node
,
texture_path
:
String
)
->
void
:
if
not
ResourceLoader
.
exists
(
texture_path
):
return
var
texture
:
Texture2D
=
load
(
texture_path
)
as
Texture2D
if
not
texture
:
return
_apply_skin_recursive
(
node
,
texture
)
static
func
_apply_skin_recursive
(
node
:
Node
,
texture
:
Texture2D
)
->
void
:
if
node
is
MeshInstance3D
:
var
mesh_inst
:
MeshInstance3D
=
node
as
MeshInstance3D
var
mat
:
StandardMaterial3D
=
StandardMaterial3D
.
new
()
mat
.
albedo_texture
=
texture
mat
.
roughness
=
0.5
mesh_inst
.
material_override
=
mat
for
child
:
Node
in
node
.
get_children
():
_apply_skin_recursive
(
child
,
texture
)
## 자식 노드 중 AnimationPlayer 탐색
static
func
find_animation_player
(
node
:
Node
)
->
AnimationPlayer
:
if
node
is
AnimationPlayer
:
return
node
as
AnimationPlayer
for
child
:
Node
in
node
.
get_children
():
var
res
:
AnimationPlayer
=
find_animation_player
(
child
)
if
res
:
return
res
return
null
## 자식 노드 중 Skeleton3D 탐색
static
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
## 유닛의 오른손에 지정된 무기 모델을 런타임 장착
static
func
attach_weapon
(
model_instance
:
Node3D
,
unit_data
:
UnitData
)
->
void
:
if
not
model_instance
or
not
unit_data
:
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
(
"UnitHelper: 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. 유닛 종류에 따른 무기 설정 분기
var
weapon_scene_path
:
String
=
""
var
weapon_scale
:
Vector3
=
Vector3
.
ONE
var
weapon_rotation
:
Vector3
=
Vector3
.
ZERO
var
weapon_position
:
Vector3
=
Vector3
.
ZERO
var
texture_path
:
String
=
""
if
unit_data
.
unit_id
==
"Unit_Guardian"
:
# 가디언 창 (azure_spear)
weapon_scene_path
=
"res://assets/models/items/weapons/azure_spear.fbx"
texture_path
=
"res://assets/models/items/weapons/azure_spear_0.png"
else
:
# 기본값: Striker 검 (azure_blade)
weapon_scene_path
=
"res://assets/models/items/weapons/azure_blade.fbx"
texture_path
=
"res://assets/models/items/weapons/azure_blade_0.png"
# 3. 무기 로드 및 인스턴스화
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
weapon_inst
.
scale
=
weapon_scale
weapon_inst
.
rotation_degrees
=
weapon_rotation
weapon_inst
.
position
=
weapon_position
# 무기 텍스처 매핑
apply_skin
(
weapon_inst
,
texture_path
)
bone_attachment
.
add_child
(
weapon_inst
)
print
(
"UnitHelper: Attached weapon successfully. Unit: "
,
unit_data
.
unit_name
,
", Weapon: "
,
weapon_scene_path
.
get_file
())
## 애니메이션 내에서 모델의 로컬 정면 방향을 강제 리셋하는 루트(Armature) 트랙 정화
static
func
clean_root_animation_tracks
(
anim_player
:
AnimationPlayer
)
->
void
:
if
not
anim_player
:
return
# AnimationPlayer에 바인딩된 모든 애니메이션 라이브러리의 트랙 정화
for
library_name
:
StringName
in
anim_player
.
get_animation_library_list
():
var
lib
:
AnimationLibrary
=
anim_player
.
get_animation_library
(
library_name
)
if
not
lib
:
continue
for
anim_name
:
StringName
in
lib
.
get_animation_list
():
var
anim
:
Animation
=
lib
.
get_animation
(
anim_name
)
if
anim
:
var
tracks_to_remove
:
Array
[
int
]
=
[]
for
track_idx
:
int
in
range
(
anim
.
get_track_count
()):
var
path_str
:
String
=
str
(
anim
.
track_get_path
(
track_idx
))
# 최상위 루트 노드(Armature 등)의 회전/위치 강제 덮어쓰기 트랙 검출
# Skeleton3D 하위의 실제 뼈대 애니메이션 트랙은 유지하고 오직 Armature 루트 트랜스폼 트랙만 제거
if
path_str
==
"Armature:rotation"
or
path_str
==
"Armature:position"
or
\
path_str
.
begins_with
(
"Armature:"
)
and
not
"Skeleton3D"
in
path_str
:
tracks_to_remove
.
append
(
track_idx
)
# 역순으로 정렬하여 트랙 제거 시 인덱스 밀림 방지
tracks_to_remove
.
reverse
()
for
track_idx
:
int
in
tracks_to_remove
:
anim
.
remove_track
(
track_idx
)
print
(
"UnitHelper: Cleaned root and Armature transform tracks to preserve character body rotation."
)
src/entities/units/unit_helper.gd.uid
0 → 100644
View file @
3410532f
uid://dxqa2rlcobrie
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