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
63afeb5e
Commit
63afeb5e
authored
Jun 23, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
타일셋 적용
parent
7601e2d0
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
322 additions
and
29 deletions
+322
-29
assets/models/tile/tile_natvigate.glb
assets/models/tile/tile_natvigate.glb
+0
-0
assets/models/tile/tile_natvigate.glb.import
assets/models/tile/tile_natvigate.glb.import
+42
-0
assets/models/tile/tile_natvigate_0.jpg
assets/models/tile/tile_natvigate_0.jpg
+0
-0
assets/models/tile/tile_natvigate_0.jpg.import
assets/models/tile/tile_natvigate_0.jpg.import
+44
-0
assets/models/tile/tile_wooden.glb
assets/models/tile/tile_wooden.glb
+0
-0
assets/models/tile/tile_wooden.glb.import
assets/models/tile/tile_wooden.glb.import
+42
-0
assets/models/tile/tile_wooden_0.jpg
assets/models/tile/tile_wooden_0.jpg
+0
-0
assets/models/tile/tile_wooden_0.jpg.import
assets/models/tile/tile_wooden_0.jpg.import
+44
-0
src/core/main.tscn
src/core/main.tscn
+7
-14
src/entities/monsters/base_monster.gd
src/entities/monsters/base_monster.gd
+6
-0
src/entities/units/base_unit.gd
src/entities/units/base_unit.gd
+24
-10
src/map/tile_mesh_library.tres
src/map/tile_mesh_library.tres
+108
-0
src/ui/hud.gd
src/ui/hud.gd
+5
-5
No files found.
assets/models/tile/tile_natvigate.glb
0 → 100644
View file @
63afeb5e
File added
assets/models/tile/tile_natvigate.glb.import
0 → 100644
View file @
63afeb5e
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://rraupg42y6ff"
path="res://.godot/imported/tile_natvigate.glb-d1a0162fb96d2ee66536d7febab168f3.scn"
[deps]
source_file="res://assets/models/tile/tile_natvigate.glb"
dest_files=["res://.godot/imported/tile_natvigate.glb-d1a0162fb96d2ee66536d7febab168f3.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
assets/models/tile/tile_natvigate_0.jpg
0 → 100644
View file @
63afeb5e
1.22 MB
assets/models/tile/tile_natvigate_0.jpg.import
0 → 100644
View file @
63afeb5e
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://1yhhmgh61u03"
path.s3tc="res://.godot/imported/tile_natvigate_0.jpg-6e181a06513bc19c57c48ef799ed1b00.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
generator_parameters={
"md5": "cf3110f01f21dc4584b8e86a27b4c876"
}
[deps]
source_file="res://assets/models/tile/tile_natvigate_0.jpg"
dest_files=["res://.godot/imported/tile_natvigate_0.jpg-6e181a06513bc19c57c48ef799ed1b00.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
assets/models/tile/tile_wooden.glb
0 → 100644
View file @
63afeb5e
File added
assets/models/tile/tile_wooden.glb.import
0 → 100644
View file @
63afeb5e
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://ceo5a5tyl3k5p"
path="res://.godot/imported/tile_wooden.glb-310a2ff2f5700248848d516d347039c4.scn"
[deps]
source_file="res://assets/models/tile/tile_wooden.glb"
dest_files=["res://.godot/imported/tile_wooden.glb-310a2ff2f5700248848d516d347039c4.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
assets/models/tile/tile_wooden_0.jpg
0 → 100644
View file @
63afeb5e
2.62 MB
assets/models/tile/tile_wooden_0.jpg.import
0 → 100644
View file @
63afeb5e
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bibh50cplv1tp"
path.s3tc="res://.godot/imported/tile_wooden_0.jpg-24da3ec6fc4feca6a0f47641c0ba9036.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
generator_parameters={
"md5": "fb66fca216e35d4d9e0ac44740ca9799"
}
[deps]
source_file="res://assets/models/tile/tile_wooden_0.jpg"
dest_files=["res://.godot/imported/tile_wooden_0.jpg-24da3ec6fc4feca6a0f47641c0ba9036.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
src/core/main.tscn
View file @
63afeb5e
[gd_scene format=3 uid="uid://bj2p5iv0c10v6"]
[gd_scene format=3 uid="uid://bj2p5iv0c10v6"]
[ext_resource type="MeshLibrary" uid="uid://ddc7y16q0whgv" path="res://src/map/tile_mesh_library.tres" id="1_nxx65"]
[ext_resource type="Script" uid="uid://dd1xgi6hnpuvs" path="res://src/core/rts_camera.gd" id="1_rts_cam"]
[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="Script" uid="uid://cq7r51whh6po" path="res://src/core/stage_manager.gd" id="2_stage_mgr"]
[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="PackedScene" uid="uid://dimlohck6ebg7" path="res://src/entities/monsters/noble_man/noble_man_unit.tscn" id="3_base_monster"]
...
@@ -9,12 +10,6 @@
...
@@ -9,12 +10,6 @@
[sub_resource type="NavigationMesh" id="NavigationMesh_map"]
[sub_resource type="NavigationMesh" id="NavigationMesh_map"]
agent_height = 1.0
agent_height = 1.0
[sub_resource type="BoxShape3D" id="BoxShape3D_ground"]
size = Vector3(20, 1, 20)
[sub_resource type="BoxMesh" id="BoxMesh_ground"]
size = Vector3(20, 1, 20)
[sub_resource type="Curve3D" id="Curve3D_path"]
[sub_resource type="Curve3D" id="Curve3D_path"]
_data = {
_data = {
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -8.5, 0, -8.5, 0, 0, 0, 0, 0, 0, 8.5, 0, -8.5, 0, 0, 0, 0, 0, 0, 8.5, 0, 8.5, 0, 0, 0, 0, 0, 0, -8.5, 0, 8.5, 0, 0, 0, 0, 0, 0, -8.5, 0, -8.5),
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -8.5, 0, -8.5, 0, 0, 0, 0, 0, 0, 8.5, 0, -8.5, 0, 0, 0, 0, 0, 0, 8.5, 0, 8.5, 0, 0, 0, 0, 0, 0, -8.5, 0, 8.5, 0, 0, 0, 0, 0, 0, -8.5, 0, -8.5),
...
@@ -33,16 +28,14 @@ shadow_enabled = true
...
@@ -33,16 +28,14 @@ shadow_enabled = true
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="." unique_id=161846999]
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="." unique_id=161846999]
navigation_mesh = SubResource("NavigationMesh_map")
navigation_mesh = SubResource("NavigationMesh_map")
[node name="Ground" type="StaticBody3D" parent="NavigationRegion3D" unique_id=341047909]
[node name="GridMap" type="GridMap" parent="NavigationRegion3D" unique_id=958427223]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0)
mesh_library = ExtResource("1_nxx65")
data = {
[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/Ground" unique_id=1875970619]
"cells": PackedInt32Array(65531, 65531, 0, 65531, 65532, 0, 65531, 65533, 0, 65531, 65534, 0, 65531, 65535, 0, 65531, 0, 0, 65531, 1, 0, 65531, 2, 0, 65531, 3, 0, 65531, 4, 0, 65532, 65531, 0, 65532, 65532, 1, 65532, 65533, 1, 65532, 65534, 1, 65532, 65535, 1, 65532, 0, 1, 65532, 1, 1, 65532, 2, 1, 65532, 3, 1, 65532, 4, 0, 65533, 65531, 0, 65533, 65532, 1, 65533, 65533, 1, 65533, 65534, 1, 65533, 65535, 1, 65533, 0, 1, 65533, 1, 1, 65533, 2, 1, 65533, 3, 1, 65533, 4, 0, 65534, 65531, 0, 65534, 65532, 1, 65534, 65533, 1, 65534, 65534, 1, 65534, 65535, 1, 65534, 0, 1, 65534, 1, 1, 65534, 2, 1, 65534, 3, 1, 65534, 4, 0, 65535, 65531, 0, 65535, 65532, 1, 65535, 65533, 1, 65535, 65534, 1, 65535, 65535, 1, 65535, 0, 1, 65535, 1, 1, 65535, 2, 1, 65535, 3, 1, 65535, 4, 0, 0, 65531, 0, 0, 65532, 1, 0, 65533, 1, 0, 65534, 1, 0, 65535, 1, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0, 4, 0, 1, 65531, 0, 1, 65532, 1, 1, 65533, 1, 1, 65534, 1, 1, 65535, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 4, 0, 2, 65531, 0, 2, 65532, 1, 2, 65533, 1, 2, 65534, 1, 2, 65535, 1, 2, 0, 1, 2, 1, 1, 2, 2, 1, 2, 3, 1, 2, 4, 0, 3, 65531, 0, 3, 65532, 1, 3, 65533, 1, 3, 65534, 1, 3, 65535, 1, 3, 0, 1, 3, 1, 1, 3, 2, 1, 3, 3, 1, 3, 4, 0, 4, 65531, 0, 4, 65532, 0, 4, 65533, 0, 4, 65534, 0, 4, 65535, 0, 4, 0, 0, 4, 1, 0, 4, 2, 0, 4, 3, 0, 4, 4, 0)
shape = SubResource("BoxShape3D_ground")
}
[node name="MeshInstance3D" type="MeshInstance3D" parent="NavigationRegion3D/Ground" unique_id=1715390279]
mesh = SubResource("BoxMesh_ground")
[node name="MonsterPath" type="Path3D" parent="." unique_id=432631624]
[node name="MonsterPath" type="Path3D" parent="." unique_id=432631624]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
curve = SubResource("Curve3D_path")
curve = SubResource("Curve3D_path")
[node name="RTSCamera" type="Camera3D" parent="." unique_id=1379842143]
[node name="RTSCamera" type="Camera3D" parent="." unique_id=1379842143]
...
...
src/entities/monsters/base_monster.gd
View file @
63afeb5e
...
@@ -36,6 +36,12 @@ func _ready() -> void:
...
@@ -36,6 +36,12 @@ func _ready() -> void:
if
detected_model_node
:
if
detected_model_node
:
_model_instance
=
detected_model_node
_model_instance
=
detected_model_node
# GridMap 타일 높이(Y=0.21)에 맞춰 모델 및 충돌 판정 영역 오프셋 보정
_model_instance
.
position
.
y
=
0.21
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"
:
if
detected_model_name
==
"noble_man"
:
_apply_noble_man_skin
(
_model_instance
)
_apply_noble_man_skin
(
_model_instance
)
...
...
src/entities/units/base_unit.gd
View file @
63afeb5e
...
@@ -91,7 +91,7 @@ func _ready() -> void:
...
@@ -91,7 +91,7 @@ func _ready() -> void:
func
_physics_process
(
delta
:
float
)
->
void
:
func
_physics_process
(
delta
:
float
)
->
void
:
if
GameManager
.
is_game_over
:
if
GameManager
.
is_game_over
or
not
unit_data
:
velocity
=
Vector3
.
ZERO
velocity
=
Vector3
.
ZERO
return
return
...
@@ -120,13 +120,23 @@ func _physics_process(delta: float) -> void:
...
@@ -120,13 +120,23 @@ func _physics_process(delta: float) -> void:
if
not
_target_monster
and
_auto_target_cooldown
<=
0.0
:
if
not
_target_monster
and
_auto_target_cooldown
<=
0.0
:
_find_nearest_target
()
_find_nearest_target
()
# 3. 상태에 따른 AI 동작 분기
# 3. 상태에 따른 AI 동작 분기
(XZ 수평 속도를 velocity에 세팅)
if
_target_monster
:
if
_target_monster
:
_process_attack_logic
(
delta
)
_process_attack_logic
(
delta
)
else
:
else
:
_process_normal_logic
(
delta
)
_process_normal_logic
(
delta
)
# 4. 3D 애니메이션 재생 업데이트
# 4. 중력 적용
var
gravity
:
float
=
ProjectSettings
.
get_setting
(
"physics/3d/default_gravity"
)
if
not
is_on_floor
():
velocity
.
y
-=
gravity
*
delta
else
:
velocity
.
y
=
-
0.1
# 바닥에 밀착되도록 약한 하향 물리 입력 유지
# 5. 물리 이동 통합 실행
move_and_slide
()
# 6. 3D 애니메이션 재생 업데이트
_update_animations
()
_update_animations
()
## 1. 공격 타겟이 존재할 때의 동작 로직 (진동 버벅임 방지 Hysteresis 적용 및 공격 중 잠금 추가)
## 1. 공격 타겟이 존재할 때의 동작 로직 (진동 버벅임 방지 Hysteresis 적용 및 공격 중 잠금 추가)
...
@@ -139,7 +149,8 @@ func _process_attack_logic(_delta: float) -> void:
...
@@ -139,7 +149,8 @@ func _process_attack_logic(_delta: float) -> void:
# 공격 모션 재생 중(공격 잠금 시간 동안)에는 무조건 이동하지 않고 멈춰서 공격 모션 유지
# 공격 모션 재생 중(공격 잠금 시간 동안)에는 무조건 이동하지 않고 멈춰서 공격 모션 유지
if
_attack_lock_timer
>
0.0
:
if
_attack_lock_timer
>
0.0
:
_is_currently_attacking
=
true
_is_currently_attacking
=
true
velocity
=
Vector3
.
ZERO
velocity
.
x
=
0.0
velocity
.
z
=
0.0
# 타겟 몬스터를 바라보도록 회전
# 타겟 몬스터를 바라보도록 회전
_look_at_target
(
_target_monster
.
global_position
)
_look_at_target
(
_target_monster
.
global_position
)
return
return
...
@@ -163,7 +174,8 @@ func _process_attack_logic(_delta: float) -> void:
...
@@ -163,7 +174,8 @@ func _process_attack_logic(_delta: float) -> void:
if
should_attack
:
if
should_attack
:
_is_currently_attacking
=
true
_is_currently_attacking
=
true
velocity
=
Vector3
.
ZERO
velocity
.
x
=
0.0
velocity
.
z
=
0.0
# 타겟 몬스터를 바라보도록 회전
# 타겟 몬스터를 바라보도록 회전
_look_at_target
(
_target_monster
.
global_position
)
_look_at_target
(
_target_monster
.
global_position
)
_try_attack
()
_try_attack
()
...
@@ -177,23 +189,25 @@ func _process_attack_logic(_delta: float) -> void:
...
@@ -177,23 +189,25 @@ func _process_attack_logic(_delta: float) -> void:
func
_process_normal_logic
(
_delta
:
float
)
->
void
:
func
_process_normal_logic
(
_delta
:
float
)
->
void
:
# 홀드 상태이거나 이동 명령이 끝난 경우 정지
# 홀드 상태이거나 이동 명령이 끝난 경우 정지
if
_is_holding
or
_nav_agent
.
is_navigation_finished
():
if
_is_holding
or
_nav_agent
.
is_navigation_finished
():
velocity
=
Vector3
.
ZERO
velocity
.
x
=
0.0
velocity
.
z
=
0.0
else
:
else
:
_navigate_to_target
(
_delta
)
_navigate_to_target
(
_delta
)
## 네비게이션 타겟 방향으로 캐릭터 이동
## 네비게이션 타겟 방향으로 캐릭터 이동
func
_navigate_to_target
(
_delta
:
float
)
->
void
:
func
_navigate_to_target
(
_delta
:
float
)
->
void
:
if
_nav_agent
.
is_navigation_finished
():
if
_nav_agent
.
is_navigation_finished
():
velocity
=
Vector3
.
ZERO
velocity
.
x
=
0.0
velocity
.
z
=
0.0
return
return
var
next_path_pos
:
Vector3
=
_nav_agent
.
get_next_path_position
()
var
next_path_pos
:
Vector3
=
_nav_agent
.
get_next_path_position
()
var
current_pos
:
Vector3
=
global_position
var
current_pos
:
Vector3
=
global_position
var
new_velocity
:
Vector3
=
(
next_path_pos
-
current_pos
)
.
normalized
()
*
unit_data
.
move_speed
var
new_velocity
:
Vector3
=
(
next_path_pos
-
current_pos
)
.
normalized
()
*
unit_data
.
move_speed
#
Y축 속도는 고정하고 평면 속도만 적용
#
XZ 속도 설정 (Y 속도는 _physics_process의 중력 연산에 맡김)
velocity
=
Vector3
(
new_velocity
.
x
,
0.0
,
new_velocity
.
z
)
velocity
.
x
=
new_velocity
.
x
move_and_slide
()
velocity
.
z
=
new_velocity
.
z
# 이동 방향 바라보도록 회전
# 이동 방향 바라보도록 회전
if
current_pos
.
distance_to
(
next_path_pos
)
>
0.2
:
if
current_pos
.
distance_to
(
next_path_pos
)
>
0.2
:
...
...
src/map/tile_mesh_library.tres
0 → 100644
View file @
63afeb5e
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/ui/hud.gd
View file @
63afeb5e
...
@@ -115,17 +115,17 @@ func _on_spawn_pressed() -> void:
...
@@ -115,17 +115,17 @@ func _on_spawn_pressed() -> void:
# 맵 중앙 스폰 존(0, 0) 기준 분산 스폰 좌표 지정
# 맵 중앙 스폰 존(0, 0) 기준 분산 스폰 좌표 지정
var
spawn_offset
:
Vector3
=
Vector3
(
var
spawn_offset
:
Vector3
=
Vector3
(
randf_range
(
-
2.0
,
2.0
),
randf_range
(
-
2.0
,
2.0
),
0.1
,
2.5
,
randf_range
(
-
2.0
,
2.0
)
randf_range
(
-
2.0
,
2.0
)
)
)
# 스폰 위치 설정 및 능력치 주입
if
new_unit
is
Node3D
:
(
new_unit
as
Node3D
)
.
global_position
=
spawn_offset
new_unit
.
set
(
"unit_data"
,
chosen_template
)
new_unit
.
set
(
"unit_data"
,
chosen_template
)
parent_scene
.
add_child
(
new_unit
)
parent_scene
.
add_child
(
new_unit
)
# 씬 트리에 추가된 이후에 global_position을 주입해야 월드 좌표계 연산이 올바르게 반영됩니다.
if
new_unit
is
Node3D
:
(
new_unit
as
Node3D
)
.
global_position
=
spawn_offset
print
(
"Spawned random unit: "
,
chosen_template
.
unit_name
,
" at position "
,
spawn_offset
)
print
(
"Spawned random unit: "
,
chosen_template
.
unit_name
,
" at position "
,
spawn_offset
)
# 상시 노출되는 게임 재시작 버튼 클릭 처리
# 상시 노출되는 게임 재시작 버튼 클릭 처리
...
...
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