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
474297e4
Commit
474297e4
authored
Jun 23, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
유닛, 몬스터 상속 작업 전
parent
711b84d0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
134 additions
and
92 deletions
+134
-92
src/autoload/data_manager.gd
src/autoload/data_manager.gd
+46
-27
src/core/stage_manager.gd
src/core/stage_manager.gd
+9
-6
src/entities/monsters/base_monster.gd
src/entities/monsters/base_monster.gd
+68
-59
src/entities/monsters/monster_data.gd
src/entities/monsters/monster_data.gd
+10
-0
src/entities/monsters/monster_data.gd.uid
src/entities/monsters/monster_data.gd.uid
+1
-0
No files found.
src/autoload/data_manager.gd
View file @
474297e4
...
@@ -4,9 +4,12 @@ extends Node
...
@@ -4,9 +4,12 @@ extends Node
# 유닛 리소스 템플릿 목록
# 유닛 리소스 템플릿 목록
var
unit_templates
:
Array
[
UnitData
]
=
[]
var
unit_templates
:
Array
[
UnitData
]
=
[]
# 몬스터 리소스 템플릿 목록
var
monster_templates
:
Array
[
MonsterData
]
=
[]
func
_ready
()
->
void
:
func
_ready
()
->
void
:
_initialize_unit_templates
()
_initialize_unit_templates
()
_initialize_monster_templates
()
## 5종의 유닛 능력치 데이터 초기 셋업
## 5종의 유닛 능력치 데이터 초기 셋업
func
_initialize_unit_templates
()
->
void
:
func
_initialize_unit_templates
()
->
void
:
...
@@ -46,35 +49,51 @@ func _initialize_unit_templates() -> void:
...
@@ -46,35 +49,51 @@ func _initialize_unit_templates() -> void:
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 (고화력 대형 유닛)
## 몬스터 능력치 데이터 초기 셋업
#var slayer: UnitData = UnitData.new()
func
_initialize_monster_templates
()
->
void
:
#
slayer.unit_id = "Unit_Slayer"
#
1. Noble Man (기본 밸런스형 몬스터)
#slayer.unit_name = "Slayer"
var
noble_man
:
MonsterData
=
MonsterData
.
new
()
#slayer.damage = 55.0
noble_man
.
monster_id
=
"noble_man"
#slayer.cooldown = 1.8
noble_man
.
monster_name
=
"Noble Man"
#slayer.move_speed = 3.5
noble_man
.
hp
=
100.0
#slayer.attack_range = 1.6
noble_man
.
speed
=
2.0
#slayer.is_ranged = false
noble_man
.
gold_reward
=
15
#slayer.unit_color = Color(0.85, 0.12, 0.12, 1.0) # 진적색
noble_man
.
model_name
=
"noble_man"
#unit_templates.append(slayer
)
monster_templates
.
append
(
noble_man
)
# 5. Archmage (극단적 극딜 마법 유닛)
# 2. Zombie (고체력 저속형 몬스터)
#var archmage: UnitData = UnitData.new()
var
zombie
:
MonsterData
=
MonsterData
.
new
()
#archmage.unit_id = "Unit_Archmage"
zombie
.
monster_id
=
"zombie"
#archmage.unit_name = "Archmage"
zombie
.
monster_name
=
"Zombie"
#archmage.damage = 110.0
zombie
.
hp
=
150.0
#archmage.cooldown = 3.0
zombie
.
speed
=
1.5
#archmage.move_speed = 3.0
zombie
.
gold_reward
=
20
#archmage.attack_range = 12.0
zombie
.
model_name
=
"zombie"
#archmage.is_ranged = true
monster_templates
.
append
(
zombie
)
#archmage.unit_color = Color(0.55, 0.12, 0.85, 1.0) # 보라색
#unit_templates.append(archmage)
## 특정 스테이지에 따른 몬스터 체력(HP) 반환
## 특정 스테이지 스케일이 반영된 완성된 MonsterData 인스턴스를 반환
func
get_monster_hp
(
stage
:
int
)
->
float
:
func
get_stage_monster_data
(
monster_id
:
String
,
stage
:
int
)
->
MonsterData
:
return
100.0
+
(
stage
-
1
)
*
50.0
var
template
:
MonsterData
=
null
for
t
in
monster_templates
:
if
t
.
monster_id
==
monster_id
:
template
=
t
break
## 특정 스테이지에 따른 몬스터 처치 보상 골드 반환
if
not
template
:
push_error
(
"DataManager: Monster template not found for ID: "
+
monster_id
)
return
null
# 복제하여 런타임용 데이터 독립 인스턴스 생성
var
stage_data
=
template
.
duplicate
(
true
)
as
MonsterData
# 체력 스케일링: 기본 체력 + (스테이지 - 1) * 50
stage_data
.
hp
=
template
.
hp
+
(
stage
-
1
)
*
50.0
# 처치 골드 리워드 스케일링
stage_data
.
gold_reward
=
get_monster_gold_reward
(
stage
)
return
stage_data
## 특정 스테이지에 따른 몬스터 처치 보상 골드 반환 (기본 연산용)
func
get_monster_gold_reward
(
stage
:
int
)
->
int
:
func
get_monster_gold_reward
(
stage
:
int
)
->
int
:
if
stage
>=
20
:
return
100
if
stage
>=
20
:
return
100
elif
stage
>=
15
:
return
60
+
(
stage
-
15
)
*
8
elif
stage
>=
15
:
return
60
+
(
stage
-
15
)
*
8
...
...
src/core/stage_manager.gd
View file @
474297e4
...
@@ -91,13 +91,16 @@ func _on_spawn_timer_timeout() -> void:
...
@@ -91,13 +91,16 @@ func _on_spawn_timer_timeout() -> void:
var
monster_instance
:
Node
=
selected_scene
.
instantiate
()
var
monster_instance
:
Node
=
selected_scene
.
instantiate
()
_path_node
.
add_child
(
monster_instance
)
_path_node
.
add_child
(
monster_instance
)
# 몬스터 초기화 (
HP, 보상 골드 설정
)
# 몬스터 초기화 (
리소스 ID 판정 및 스테이지 데이터 획득
)
var
stage
:
int
=
GameManager
.
current_stage
var
stage
:
int
=
GameManager
.
current_stage
var
monster_hp
:
float
=
DataManager
.
get_monster_hp
(
stage
)
var
monster_id
:
String
=
"noble_man"
# 기본값
var
monster_gold
:
int
=
DataManager
.
get_monster_gold_reward
(
stage
)
var
scene_path
:
String
=
selected_scene
.
resource_path
.
to_lower
()
if
"zombie"
in
scene_path
:
if
monster_instance
.
has_method
(
"initialize_monster"
):
monster_id
=
"zombie"
monster_instance
.
call
(
"initialize_monster"
,
monster_hp
,
monster_gold
)
var
monster_data
:
MonsterData
=
DataManager
.
get_stage_monster_data
(
monster_id
,
stage
)
if
monster_data
and
monster_instance
.
has_method
(
"initialize_monster"
):
monster_instance
.
call
(
"initialize_monster"
,
monster_data
)
GameManager
.
increment_monster_count
()
GameManager
.
increment_monster_count
()
...
...
src/entities/monsters/base_monster.gd
View file @
474297e4
class_name
BaseMonster
class_name
BaseMonster
extends
PathFollow3D
extends
PathFollow3D
## 기본 몬스터 클래스 (
Path3D 상하위에서 경로를 따라 회전하며 피격/사망 처리됨
)
## 기본 몬스터 클래스 (
MonsterData를 기반으로 스펙 및 모델을 설정하고 이동/피격 처리
)
# 몬스터 능력치 설정
@
export
var
monster_data
:
MonsterData
# 몬스터 실시간 스펙 (MonsterData 주입 수치를 따름)
@
export
var
speed
:
float
=
2.0
@
export
var
speed
:
float
=
2.0
var
max_hp
:
float
=
100.0
var
max_hp
:
float
=
100.0
var
current_hp
:
float
=
100.0
var
current_hp
:
float
=
100.0
...
@@ -21,57 +23,64 @@ func _ready() -> void:
...
@@ -21,57 +23,64 @@ func _ready() -> void:
# PathFollow3D 루프 설정 활성화 (경로 끝 도달 시 처음으로 돌아감)
# PathFollow3D 루프 설정 활성화 (경로 끝 도달 시 처음으로 돌아감)
loop
=
true
loop
=
true
# 자식 노드 중 3D 모델(noble_man 등) 노드 자동 탐색 및 초기화 (base_unit.gd 매커니즘 준수)
# 만약 씬 내부에 monster_data 리소스가 사전 설정되어 있다면 바로 로드 실행
#var model_names: Array[String] = ["noble_man", "zombie"]
if
monster_data
:
var
model_names
:
Array
[
String
]
=
[
"zombie"
]
_setup_monster_from_data
()
var
detected_model_node
:
Node3D
=
null
var
detected_model_name
:
String
=
""
for
m_name
:
String
in
model_names
:
## 몬스터 데이터 기반 모델 및 충돌, 스킨/애니메이션 정렬 셋업
var
node
:
Node3D
=
get_node_or_null
(
m_name
)
as
Node3D
func
_setup_monster_from_data
()
->
void
:
if
node
:
if
not
monster_data
:
detected_model_node
=
node
return
detected_model_name
=
m_name
break
if
not
detected_model_node
:
var
m_name
:
String
=
monster_data
.
model_name
var
node
:
Node3D
=
get_node_or_null
(
m_name
)
as
Node3D
if
not
node
:
push_error
(
"BaseMonster: Model node '"
+
m_name
+
"' not found under children."
)
return
return
_model_instance
=
node
print
(
"BaseMonster: Identified model ["
,
m_name
,
"] from MonsterData."
)
_model_instance
=
detected_model_node
if
m_name
==
"noble_man"
:
#GridMap 타일 높이(Y=0.21)에 맞춰 모델 및 충돌 판정 영역 오프셋 보정
#_model_instance.position.y = 0
var
monster_area
=
get_node_or_null
(
"MonsterArea"
)
#if monster_area and monster_area is Node3D:
#monster_area.position.y = 0.71
if
detected_model_name
==
"noble_man"
:
_apply_noble_man_skin
(
_model_instance
)
_apply_noble_man_skin
(
_model_instance
)
elif
detected_model
_name
==
"zombie"
:
elif
m
_name
==
"zombie"
:
_apply_zombie_skin
(
_model_instance
)
_apply_zombie_skin
(
_model_instance
)
_model_anim_player
=
_find_animation_player
(
_model_instance
)
_model_anim_player
=
_find_animation_player
(
_model_instance
)
if
not
_model_anim_player
:
if
_model_anim_player
:
return
print
(
"BaseMonster: Linked model AnimationPlayer: "
,
m_name
)
print
(
"BaseMonster: Linked model AnimationPlayer: "
,
detected_model_name
)
# 모델명_animations.tres 또는 모델명_anims.tres 라이브러리를 동적으로 로드하여 등록
# 모델명_animations.tres 또는 모델명_anims.tres 라이브러리를 동적으로 로드하여 등록 (base_unit.gd 방식 준수)
var
anim_lib_path
:
String
=
"res://assets/models/monsters/"
+
m_name
+
"/"
+
m_name
+
"_animations.tres"
# 단, 씬 파일에서 이미 기본 라이브러리("")로 등록된 경우 중복 등록 방지
var
anim_lib_path_alt
:
String
=
"res://assets/models/monsters/"
+
m_name
+
"/"
+
m_name
+
"_anims.tres"
var
anim_lib_path
:
String
=
"res://assets/models/monsters/"
+
detected_model_name
+
"/"
+
detected_model_name
+
"_animations.tres"
var
path_to_load
:
String
=
""
if
anim_lib_path
!=
""
:
if
ResourceLoader
.
exists
(
anim_lib_path
):
var
lib
:
AnimationLibrary
=
load
(
anim_lib_path
)
as
AnimationLibrary
path_to_load
=
anim_lib_path
if
lib
and
not
_model_anim_player
.
has_animation_library
(
detected_model_name
):
elif
ResourceLoader
.
exists
(
anim_lib_path_alt
):
_model_anim_player
.
add_animation_library
(
detected_model_name
,
lib
)
path_to_load
=
anim_lib_path_alt
print
(
"BaseMonster: Loaded and registered "
,
detected_model_name
,
" animations library successfully."
)
if
path_to_load
!=
""
:
var
lib
:
AnimationLibrary
=
load
(
path_to_load
)
as
AnimationLibrary
if
lib
and
not
_model_anim_player
.
has_animation_library
(
m_name
):
var
already_registered
:
bool
=
false
for
existing_lib_name
in
_model_anim_player
.
get_animation_library_list
():
if
_model_anim_player
.
get_animation_library
(
existing_lib_name
)
==
lib
:
already_registered
=
true
break
if
not
already_registered
:
_model_anim_player
.
add_animation_library
(
m_name
,
lib
)
print
(
"BaseMonster: Loaded and registered "
,
m_name
,
" animations library successfully."
)
else
:
else
:
print
(
"BaseMonster: Animation library already present (scene-bound or already added)
."
)
print
(
"BaseMonster: Animation library already registered on model under another name
."
)
# 초기 Idle 애니메이션 재생 시도
# 초기 Idle 애니메이션 재생 시도
# 탐색 순서: 기본 라이브러리("") -> 동적 등록(모델명/) -> FBX 내장
var
init_idle
:
String
=
_resolve_anim_name
(
_model_anim_player
,
m_name
,
"Idle"
)
var
init_idle
:
String
=
_resolve_anim_name
(
_model_anim_player
,
detected_model_name
,
"Idle"
)
if
init_idle
!=
""
:
if
init_idle
!=
""
:
_model_anim_player
.
play
(
init_idle
)
_model_anim_player
.
play
(
init_idle
)
print
(
"BaseMonster: Playing initial Idle: "
,
init_idle
)
print
(
"BaseMonster: Playing initial Idle: "
,
init_idle
)
## 몬스터 자식 메쉬에 noble_man_0.png 텍스처를 입히는 재귀 함수
## 몬스터 자식 메쉬에 noble_man_0.png 텍스처를 입히는 재귀 함수
func
_apply_noble_man_skin
(
node
:
Node
)
->
void
:
func
_apply_noble_man_skin
(
node
:
Node
)
->
void
:
if
node
is
MeshInstance3D
:
if
node
is
MeshInstance3D
:
...
@@ -116,12 +125,19 @@ func _physics_process(delta: float) -> void:
...
@@ -116,12 +125,19 @@ func _physics_process(delta: float) -> void:
_update_monster_animation
()
_update_monster_animation
()
## 몬스터 초기화 (StageManager에 의해 스폰 시 호출됨)
## 몬스터 초기화 (StageManager에 의해 스폰 시 호출됨)
func
initialize_monster
(
hp
:
float
,
reward
:
int
)
->
void
:
func
initialize_monster
(
data
:
MonsterData
)
->
void
:
max_hp
=
hp
monster_data
=
data
current_hp
=
hp
gold_reward
=
reward
max_hp
=
data
.
hp
current_hp
=
data
.
hp
speed
=
data
.
speed
gold_reward
=
data
.
gold_reward
is_dead
=
false
is_dead
=
false
# _ready() 시점에 데이터가 비어 모델 셋업을 보류했던 경우 여기서 실행
if
not
_model_instance
:
_setup_monster_from_data
()
# 체력바 생성
# 체력바 생성
_create_hp_bar
()
_create_hp_bar
()
...
@@ -199,17 +215,14 @@ func _update_monster_animation() -> void:
...
@@ -199,17 +215,14 @@ func _update_monster_animation() -> void:
return
return
var
model_name
:
String
=
""
var
model_name
:
String
=
""
if
_model_instance
:
if
monster_data
:
model_name
=
monster_data
.
model_name
elif
_model_instance
:
model_name
=
_model_instance
.
name
model_name
=
_model_instance
.
name
# 걷기 애니메이션 탐색 순서:
# 1. 씬 바인딩 기본 라이브러리("") -> "Walking"
# 2. 동적 등록 라이브러리 -> "모델명/Walking"
# 3. FBX 내장 트랙 -> "Armature|Walking"
var
anim_name
:
String
=
_resolve_anim_name
(
_model_anim_player
,
model_name
,
"Walking"
)
var
anim_name
:
String
=
_resolve_anim_name
(
_model_anim_player
,
model_name
,
"Walking"
)
if
anim_name
!=
""
:
if
anim_name
!=
""
:
# 걷는 애니메이션 루프 활성화
var
anim
:
Animation
=
_model_anim_player
.
get_animation
(
anim_name
)
var
anim
:
Animation
=
_model_anim_player
.
get_animation
(
anim_name
)
if
anim
:
if
anim
:
anim
.
loop_mode
=
Animation
.
LOOP_LINEAR
anim
.
loop_mode
=
Animation
.
LOOP_LINEAR
...
@@ -230,16 +243,12 @@ func _find_animation_player(node: Node) -> AnimationPlayer:
...
@@ -230,16 +243,12 @@ func _find_animation_player(node: Node) -> AnimationPlayer:
return
null
return
null
## 헬퍼: 애니메이션 이름 탐색 (기본 라이브러리 -> 모델명 라이브러리 -> FBX 내장 순)
## 헬퍼: 애니메이션 이름 탐색 (기본 라이브러리 -> 모델명 라이브러리 -> FBX 내장 순)
## anim_base_name: "Walking", "Idle", "Running" 등 라이브러리 키 없는 기본 이름
func
_resolve_anim_name
(
player
:
AnimationPlayer
,
model_name
:
String
,
anim_base_name
:
String
)
->
String
:
func
_resolve_anim_name
(
player
:
AnimationPlayer
,
model_name
:
String
,
anim_base_name
:
String
)
->
String
:
# 1순위: 씬에서 기본 라이브러리("")로 바인딩된 경우 (noble_man.tscn 방식)
if
player
.
has_animation
(
anim_base_name
):
if
player
.
has_animation
(
anim_base_name
):
return
anim_base_name
return
anim_base_name
# 2순위: 동적으로 등록된 모델명 라이브러리
var
lib_anim
:
String
=
model_name
+
"/"
+
anim_base_name
var
lib_anim
:
String
=
model_name
+
"/"
+
anim_base_name
if
player
.
has_animation
(
lib_anim
):
if
player
.
has_animation
(
lib_anim
):
return
lib_anim
return
lib_anim
# 3순위: FBX 내장 Armature| 접두사 트랙
var
fbx_anim
:
String
=
"Armature|"
+
anim_base_name
var
fbx_anim
:
String
=
"Armature|"
+
anim_base_name
if
player
.
has_animation
(
fbx_anim
):
if
player
.
has_animation
(
fbx_anim
):
return
fbx_anim
return
fbx_anim
...
...
src/entities/monsters/monster_data.gd
0 → 100644
View file @
474297e4
class_name
MonsterData
extends
Resource
## 몬스터의 기획 능력치 및 메쉬 정보를 정의하는 커스텀 리소스 (MonsterData)
@
export
var
monster_id
:
String
=
""
@
export
var
monster_name
:
String
=
""
@
export
var
hp
:
float
=
100.0
@
export
var
speed
:
float
=
2.0
@
export
var
gold_reward
:
int
=
15
@
export
var
model_name
:
String
=
""
# 자식 노드로 들어갈 3D 모델 노드 이름 (예: "noble_man", "zombie")
src/entities/monsters/monster_data.gd.uid
0 → 100644
View file @
474297e4
uid://c4fjd2powdrha
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