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
3dd6eba7
Commit
3dd6eba7
authored
Jul 16, 2026
by
Gavin An
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
맵 작업 전
parent
dd43f717
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
116 additions
and
111 deletions
+116
-111
sandbox/map/stage_1_desert_preview.tscn
sandbox/map/stage_1_desert_preview.tscn
+85
-0
src/core/rts_camera.gd
src/core/rts_camera.gd
+14
-94
src/ui/stage_selection/stage_selection.tscn
src/ui/stage_selection/stage_selection.tscn
+17
-17
No files found.
sandbox/map/stage_1_desert_preview.tscn
0 → 100644
View file @
3dd6eba7
[gd_scene format=3 uid="uid://bnovncfnp7suw"]
[ext_resource type="PackedScene" uid="uid://bqtcnfyfplvsr" path="res://src/map/background/desert.tscn" id="1_fd8ui"]
[ext_resource type="PackedScene" uid="uid://doj12ce3mmosn" path="res://src/map/stages/stage_1_map.tscn" id="2_hul3p"]
[sub_resource type="Gradient" id="Gradient_dc7hf"]
offsets = PackedFloat32Array(0.2, 1)
colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1)
[sub_resource type="FastNoiseLite" id="FastNoiseLite_11m5b"]
noise_type = 2
frequency = 0.03
cellular_jitter = 3.0
cellular_return_type = 0
domain_warp_enabled = true
domain_warp_type = 1
domain_warp_amplitude = 50.0
domain_warp_fractal_type = 2
domain_warp_fractal_lacunarity = 1.5
domain_warp_fractal_gain = 1.0
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_htwul"]
noise = SubResource("FastNoiseLite_11m5b")
color_ramp = SubResource("Gradient_dc7hf")
seamless = true
[sub_resource type="Terrain3DMaterial" id="Terrain3DMaterial_1of3m"]
_shader_parameters = {
&"bias_distance": null,
&"blend_sharpness": null,
&"depth_blur": null,
&"enable_macro_variation": null,
&"enable_projection": null,
&"flat_terrain_normals": null,
&"macro_variation1": null,
&"macro_variation2": null,
&"macro_variation_slope": null,
&"mipmap_bias": null,
&"noise1_angle": null,
&"noise1_offset": null,
&"noise1_scale": null,
&"noise2_scale": null,
&"noise_texture": SubResource("NoiseTexture2D_htwul"),
&"projection_threshold": null
}
show_checkered = true
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8t5t6"]
transparency = 4
cull_mode = 2
vertex_color_use_as_albedo = true
backlight_enabled = true
backlight = Color(0.5, 0.5, 0.5, 1)
distance_fade_mode = 1
distance_fade_min_distance = 128.0
distance_fade_max_distance = 96.0
[sub_resource type="Terrain3DMeshAsset" id="Terrain3DMeshAsset_o05ja"]
generated_type = 1
height_offset = 0.5
material_override = SubResource("StandardMaterial3D_8t5t6")
last_lod = 0
last_shadow_lod = 0
lod0_range = 128.0
[sub_resource type="Terrain3DAssets" id="Terrain3DAssets_h3i0q"]
mesh_list = Array[Terrain3DMeshAsset]([SubResource("Terrain3DMeshAsset_o05ja")])
[node name="Stage1DesertPreview" type="Node3D" unique_id=150272044]
[node name="DesertBackground" parent="." unique_id=2116734893 instance=ExtResource("1_fd8ui")]
material = SubResource("Terrain3DMaterial_1of3m")
assets = SubResource("Terrain3DAssets_h3i0q")
[node name="Stage1Map" parent="." unique_id=875122487 instance=ExtResource("2_hul3p")]
[node name="PreviewDirectionalLight" type="DirectionalLight3D" parent="." unique_id=322386492]
transform = Transform3D(0.81915206, -0.46984634, 0.32898995, 0, 0.57357645, 0.81915206, -0.57357645, -0.6710101, 0.46984634, 0, 0, 0)
light_energy = 2.0
shadow_enabled = true
[node name="PreviewCamera" type="Camera3D" parent="." unique_id=1634314730]
transform = Transform3D(1, 0, 0, 0, 0.44721356, 0.89442724, 0, -0.89442724, 0.44721356, 0, 22, 11)
current = true
fov = 50.0
src/core/rts_camera.gd
View file @
3dd6eba7
class_name
RTSCamera
class_name
RTSCamera
extends
Camera3D
extends
Camera3D
##
RTS 스타일 탑다운 3D 카메라 컨트롤러
##
하늘에서 전장을 살짝 비스듬히 내려다보는 고정 카메라입니다.
##
키보드(WASD) 및 마우스 경계 스크롤로 평면을 이동하고 마우스 휠로 줌 조작이 가능합
니다.
##
이동, 줌인, 줌아웃 입력 없이 항상 맵 중앙을 바라봅
니다.
# 현재 카메라가 바라보고 있는 바닥의 포커스 좌표 (이곳을 중심으로 회전 및 줌이 일어남)
@
export
var
fixed_position
:
Vector3
=
Vector3
(
0.0
,
22.0
,
11.0
)
var
_target_focus
:
Vector3
=
Vector3
.
ZERO
@
export
var
fixed_target
:
Vector3
=
Vector3
.
ZERO
var
_current_zoom
:
float
=
10.0
@
export
var
fixed_fov
:
float
=
50.0
var
_target_zoom
:
float
=
10.0
func
_ready
()
->
void
:
# 초기 카메라 위치를 기준으로 포커스 좌표 역계산
# pitch 각도를 60도로 설정 (main.tscn 기본값)
var
angle_rad
:
float
=
deg_to_rad
(
60.0
)
# 초기 줌 레벨을 최대 줌 아웃(max_zoom, 가장 축소된 뷰) 상태로 설정
# Z 오프셋 = Y / tan(60) 이므로, 포커스 타겟 Z = 카메라 Z - Z 오프셋
var
z_offset
:
float
=
_current_zoom
/
tan
(
angle_rad
)
_target_focus
=
Vector3
(
global_position
.
x
,
0.0
,
global_position
.
z
-
z_offset
)
# 초기 셋업 적용
_update_camera_transform
(
60
)
func
_physics_process
(
delta
:
float
)
->
void
:
pass
# 1. 입력 방향 계산
#var direction: Vector3 = _get_input_direction()
# 줌아웃이 최대치(max_zoom) 근처일 때는 카메라 이동을 차단하고 맵 중앙으로 초점을 부드럽게 복구
#var is_max_zoom: bool = _target_zoom >= (max_zoom - 0.1)
# 2. 포커스 타겟 이동
#if is_max_zoom:
#_target_focus = _target_focus.lerp(Vector3.ZERO, delta * move_speed * 0.2)
#elif direction != Vector3.ZERO:
#_target_focus += direction * move_speed * delta
#_target_focus.x = clampf(_target_focus.x, limit_min.x, limit_max.x)
#_target_focus.z = clampf(_target_focus.z, limit_min.y, limit_max.y)
# 3. 줌 레벨 선형 보간
#if not is_equal_approx(_current_zoom, _target_zoom):
#_current_zoom = lerpf(_current_zoom, _target_zoom, delta * zoom_speed)
#
## 4. 카메라 위치 및 회전 업데이트
#_update_camera_transform(delta)
func
_unhandled_input
(
event
:
InputEvent
)
->
void
:
func
_ready
()
->
void
:
pass
_apply_fixed_view
()
# 마우스 휠을 통한 줌 조작
#if event is InputEventMouseButton:
#var mouse_event: InputEventMouseButton = event as InputEventMouseButton
#if mouse_event.is_pressed():
#if mouse_event.button_index == MOUSE_BUTTON_WHEEL_UP:
#_target_zoom = clampf(_target_zoom - zoom_step, min_zoom, max_zoom)
#elif mouse_event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
#_target_zoom = clampf(_target_zoom + zoom_step, min_zoom, max_zoom)
## 입력 방향 계산 (키보드 WASD/방향키 + 마우스 경계 스크롤)
func
_physics_process
(
_delta
:
float
)
->
void
:
#func _get_input_direction() -> Vector3:
_apply_fixed_view
()
#var dir: Vector3 = Vector3.ZERO
## 키보드 입력 체크
#if Input.is_key_pressed(KEY_A) or Input.is_action_pressed("ui_left"):
#dir.x -= 1.0
#if Input.is_key_pressed(KEY_D) or Input.is_action_pressed("ui_right"):
#dir.x += 1.0
#if Input.is_key_pressed(KEY_W) or Input.is_action_pressed("ui_up"):
#dir.z -= 1.0
#if Input.is_key_pressed(KEY_S) or Input.is_action_pressed("ui_down"):
#dir.z += 1.0
## 마우스 경계 스크롤 체크
#if enable_edge_scroll:
#var viewport: Viewport = get_viewport()
#if viewport:
#var mouse_pos: Vector2 = viewport.get_mouse_position()
#var viewport_size: Vector2 = viewport.get_visible_rect().size
#
## 마우스 포인터가 화면 크기 안에 있을 때만 스크롤 수행 (창 밖 이탈 방지)
#if mouse_pos.x >= 0.0 and mouse_pos.y >= 0.0 and mouse_pos.x <= viewport_size.x and mouse_pos.y <= viewport_size.y:
#if mouse_pos.x < edge_margin:
#dir.x -= 1.0
#elif mouse_pos.x > viewport_size.x - edge_margin:
#dir.x += 1.0
#if mouse_pos.y < edge_margin:
#dir.z -= 1.0
#elif mouse_pos.y > viewport_size.y - edge_margin:
#dir.z += 1.0
#return dir.normalized()
## 카메라의 Position과 Rotation을 업데이트
func
_apply_fixed_view
()
->
void
:
func
_update_camera_transform
(
_delta
:
float
)
->
void
:
projection
=
Camera3D
.
PROJECTION_PERSPECTIVE
# 피치 각도 60도 고정
fov
=
fixed_fov
var
angle_rad
:
float
=
deg_to_rad
(
_delta
)
global_position
=
fixed_position
var
z_offset
:
float
=
_current_zoom
/
tan
(
angle_rad
)
look_at
(
fixed_target
,
Vector3
.
UP
)
# 카메라 글로벌 좌표 설정
global_position
.
x
=
_target_focus
.
x
global_position
.
y
=
_current_zoom
global_position
.
z
=
_target_focus
.
z
+
z_offset
# 포커스 좌표를 바라보도록 설정
look_at
(
_target_focus
,
Vector3
.
UP
)
src/ui/stage_selection/stage_selection.tscn
View file @
3dd6eba7
[gd_scene
load_steps=2 format=3
]
[gd_scene
format=3 uid="uid://cwpsgfh58ymt5"
]
[ext_resource type="Script" path="res://src/ui/stage_selection/stage_selection.gd" id="1_script"]
[ext_resource type="Script"
uid="uid://dbrefonikfeul"
path="res://src/ui/stage_selection/stage_selection.gd" id="1_script"]
[node name="StageSelection" type="Control"]
[node name="StageSelection" type="Control"
unique_id=467677690
]
layout_mode = 3
layout_mode = 3
anchors_preset = 15
anchors_preset = 15
anchor_right = 1.0
anchor_right = 1.0
...
@@ -11,7 +11,7 @@ grow_horizontal = 2
...
@@ -11,7 +11,7 @@ grow_horizontal = 2
grow_vertical = 2
grow_vertical = 2
script = ExtResource("1_script")
script = ExtResource("1_script")
[node name="Background" type="ColorRect" parent="."]
[node name="Background" type="ColorRect" parent="."
unique_id=1429718646
]
layout_mode = 1
layout_mode = 1
anchors_preset = 15
anchors_preset = 15
anchor_right = 1.0
anchor_right = 1.0
...
@@ -20,7 +20,7 @@ grow_horizontal = 2
...
@@ -20,7 +20,7 @@ grow_horizontal = 2
grow_vertical = 2
grow_vertical = 2
color = Color(0.08, 0.08, 0.12, 0.95)
color = Color(0.08, 0.08, 0.12, 0.95)
[node name="VBoxContainer" type="VBoxContainer" parent="."]
[node name="VBoxContainer" type="VBoxContainer" parent="."
unique_id=1457523875
]
layout_mode = 1
layout_mode = 1
anchors_preset = 8
anchors_preset = 8
anchor_left = 0.5
anchor_left = 0.5
...
@@ -36,72 +36,72 @@ grow_vertical = 2
...
@@ -36,72 +36,72 @@ grow_vertical = 2
theme_override_constants/separation = 40
theme_override_constants/separation = 40
alignment = 1
alignment = 1
[node name="TitleLabel" type="Label" parent="VBoxContainer"]
[node name="TitleLabel" type="Label" parent="VBoxContainer"
unique_id=1834020226
]
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 36
theme_override_font_sizes/font_size = 36
text = "SELECT YOUR STAGE"
text = "SELECT YOUR STAGE"
horizontal_alignment = 1
horizontal_alignment = 1
[node name="CardsHBox" type="HBoxContainer" parent="VBoxContainer"]
[node name="CardsHBox" type="HBoxContainer" parent="VBoxContainer"
unique_id=791690049
]
layout_mode = 2
layout_mode = 2
theme_override_constants/separation = 80
theme_override_constants/separation = 80
alignment = 1
alignment = 1
[node name="Stage1Card" type="VBoxContainer" parent="VBoxContainer/CardsHBox"]
[node name="Stage1Card" type="VBoxContainer" parent="VBoxContainer/CardsHBox"
unique_id=556756294
]
custom_minimum_size = Vector2(260, 0)
custom_minimum_size = Vector2(260, 0)
layout_mode = 2
layout_mode = 2
theme_override_constants/separation = 15
theme_override_constants/separation = 15
alignment = 1
alignment = 1
[node name="MapPreview" type="ColorRect" parent="VBoxContainer/CardsHBox/Stage1Card"]
[node name="MapPreview" type="ColorRect" parent="VBoxContainer/CardsHBox/Stage1Card"
unique_id=2122678458
]
custom_minimum_size = Vector2(240, 150)
custom_minimum_size = Vector2(240, 150)
layout_mode = 2
layout_mode = 2
color = Color(0.68, 0.52, 0.32, 0.8)
color = Color(0.68, 0.52, 0.32, 0.8)
[node name="Name" type="Label" parent="VBoxContainer/CardsHBox/Stage1Card"]
[node name="Name" type="Label" parent="VBoxContainer/CardsHBox/Stage1Card"
unique_id=739926941
]
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 24
theme_override_font_sizes/font_size = 24
text = "Desert Ruins"
text = "Desert Ruins"
horizontal_alignment = 1
horizontal_alignment = 1
[node name="Description" type="Label" parent="VBoxContainer/CardsHBox/Stage1Card"]
[node name="Description" type="Label" parent="VBoxContainer/CardsHBox/Stage1Card"
unique_id=921272994
]
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 14
theme_override_font_sizes/font_size = 14
text = "A harsh desert landscape
text = "A harsh desert landscape
with sand dunes."
with sand dunes."
horizontal_alignment = 1
horizontal_alignment = 1
[node name="SelectStage1" type="Button" parent="VBoxContainer/CardsHBox/Stage1Card"]
[node name="SelectStage1" type="Button" parent="VBoxContainer/CardsHBox/Stage1Card"
unique_id=704290559
]
custom_minimum_size = Vector2(180, 45)
custom_minimum_size = Vector2(180, 45)
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 16
theme_override_font_sizes/font_size = 16
text = "Select Stage 1"
text = "Select Stage 1"
[node name="Stage2Card" type="VBoxContainer" parent="VBoxContainer/CardsHBox"]
[node name="Stage2Card" type="VBoxContainer" parent="VBoxContainer/CardsHBox"
unique_id=1933394482
]
custom_minimum_size = Vector2(260, 0)
custom_minimum_size = Vector2(260, 0)
layout_mode = 2
layout_mode = 2
theme_override_constants/separation = 15
theme_override_constants/separation = 15
alignment = 1
alignment = 1
[node name="MapPreview" type="ColorRect" parent="VBoxContainer/CardsHBox/Stage2Card"]
[node name="MapPreview" type="ColorRect" parent="VBoxContainer/CardsHBox/Stage2Card"
unique_id=1731806437
]
custom_minimum_size = Vector2(240, 150)
custom_minimum_size = Vector2(240, 150)
layout_mode = 2
layout_mode = 2
color = Color(0.24, 0.56, 0.28, 0.8)
color = Color(0.24, 0.56, 0.28, 0.8)
[node name="Name" type="Label" parent="VBoxContainer/CardsHBox/Stage2Card"]
[node name="Name" type="Label" parent="VBoxContainer/CardsHBox/Stage2Card"
unique_id=2142060680
]
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 24
theme_override_font_sizes/font_size = 24
text = "Grassland Outpost"
text = "Grassland Outpost"
horizontal_alignment = 1
horizontal_alignment = 1
[node name="Description" type="Label" parent="VBoxContainer/CardsHBox/Stage2Card"]
[node name="Description" type="Label" parent="VBoxContainer/CardsHBox/Stage2Card"
unique_id=1393079972
]
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 14
theme_override_font_sizes/font_size = 14
text = "A peaceful green outpost
text = "A peaceful green outpost
with grassy hills."
with grassy hills."
horizontal_alignment = 1
horizontal_alignment = 1
[node name="SelectStage2" type="Button" parent="VBoxContainer/CardsHBox/Stage2Card"]
[node name="SelectStage2" type="Button" parent="VBoxContainer/CardsHBox/Stage2Card"
unique_id=1188150963
]
custom_minimum_size = Vector2(180, 45)
custom_minimum_size = Vector2(180, 45)
layout_mode = 2
layout_mode = 2
theme_override_font_sizes/font_size = 16
theme_override_font_sizes/font_size = 16
...
...
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