Commit cd7db8ec authored by Gavin An's avatar Gavin An

씬 전환용 씬 생성

parent 04cccd85
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://ijauvdhevcaj"
path="res://.godot/imported/skeleton.fbx-5f64b6e7c738f429c167bbbca464a38c.scn"
[deps]
source_file="res://assets/models/monsters/skeleton/skeleton.fbx"
dest_files=["res://.godot/imported/skeleton.fbx-5f64b6e7c738f429c167bbbca464a38c.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=true
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={}
fbx/importer=0
fbx/allow_geometry_helper_nodes=false
fbx/embedded_image_handling=1
fbx/naming_version=2
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnqqei64kp0d6"
path.s3tc="res://.godot/imported/skeleton_0.png-8d5ec31802abbf51d3e84f950a09a753.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
generator_parameters={
"md5": "4b1e4e2e6b26587258cc86569a96e546"
}
[deps]
source_file="res://assets/models/monsters/skeleton/skeleton_0.png"
dest_files=["res://.godot/imported/skeleton_0.png-8d5ec31802abbf51d3e84f950a09a753.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
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -39,4 +39,4 @@ L-Defense 게임 개요 ...@@ -39,4 +39,4 @@ L-Defense 게임 개요
* (추후) 좌측에 유일 등급의 초상화가 존재. 영웅 개념 * (추후) 좌측에 유일 등급의 초상화가 존재. 영웅 개념
- 씬의 구성 - 씬의 구성
* 게임 시작 화면 -> 소환사 선택 화면 -> 스테이지 선택 화면 -> 게임 시작 * 게임 시작 화면 -> 소환사 선택 화면 -> 스테이지 선택 화면 -> 게임 시작
\ No newline at end of file
...@@ -19,6 +19,8 @@ config/icon="res://icon.svg" ...@@ -19,6 +19,8 @@ config/icon="res://icon.svg"
GameManager="*res://src/autoload/game_manager.gd" GameManager="*res://src/autoload/game_manager.gd"
DataManager="*res://src/autoload/data_manager.gd" DataManager="*res://src/autoload/data_manager.gd"
SceneChanger="*res://src/autoload/scene_changer.tscn"
[display] [display]
......
...@@ -70,6 +70,17 @@ func _initialize_monster_templates() -> void: ...@@ -70,6 +70,17 @@ func _initialize_monster_templates() -> void:
zombie.gold_reward = 20 zombie.gold_reward = 20
zombie.model_name = "zombie" zombie.model_name = "zombie"
monster_templates.append(zombie) monster_templates.append(zombie)
# 3. Skeleton (저체력 고속형 몬스터)
var skeleton: MonsterData = MonsterData.new()
skeleton.monster_id = "skeleton"
skeleton.monster_name = "Skeleton"
skeleton.hp = 80.0
skeleton.speed = 2.8
skeleton.gold_reward = 18
skeleton.model_name = "skeleton"
monster_templates.append(skeleton)
## 특정 스테이지 스케일이 반영된 완성된 MonsterData 인스턴스를 반환 ## 특정 스테이지 스케일이 반영된 완성된 MonsterData 인스턴스를 반환
func get_stage_monster_data(monster_id: String, stage: int) -> MonsterData: func get_stage_monster_data(monster_id: String, stage: int) -> MonsterData:
......
extends CanvasLayer
## 씬 전환 전용 시스템 클래스 (SceneChanger)
## 페이드 인/아웃 시각 효과를 적용하여 페이지를 부드럽게 이동시킵니다.
@onready var color_rect: ColorRect = $ColorRect
@onready var anim_player: AnimationPlayer = $AnimationPlayer
func _ready() -> void:
# 시작 시에는 투명하게 처리하고 입력을 무시하게 함
color_rect.color.a = 0.0
color_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
## 페이드 효과를 동반하여 지정한 씬으로 이동
func change_scene_to_file(target_scene_path: String) -> void:
if not anim_player:
push_error("SceneChanger: AnimationPlayer not found.")
get_tree().change_scene_to_file(target_scene_path)
return
# 1. 입력 차단 및 페이드아웃 시작
color_rect.mouse_filter = Control.MOUSE_FILTER_STOP
var is_headless: bool = DisplayServer.get_name() == "headless"
if not is_headless:
anim_player.play("fade_out")
await anim_player.animation_finished
else:
color_rect.color.a = 1.0
# 2. 실제 씬 교체
var err = get_tree().change_scene_to_file(target_scene_path)
if err != OK:
push_error("SceneChanger: Failed to load scene: " + target_scene_path + " (Error: " + str(err) + ")")
# 에러 발생 시 원상복구
color_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
color_rect.color.a = 0.0
return
# 3. 페이드인 시작
if not is_headless:
anim_player.play("fade_in")
await anim_player.animation_finished
else:
color_rect.color.a = 0.0
# 4. 입력 차단 해제
color_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
[gd_scene format=3 uid="uid://clq0wau3g8ry"]
[ext_resource type="Script" uid="uid://cmvhxmoigcktr" path="res://src/autoload/scene_changer.gd" id="1_script"]
[sub_resource type="Animation" id="Animation_fade_in"]
resource_name = "fade_in"
length = 0.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("ColorRect:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(0, 0, 0, 1), Color(0, 0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_fade_out"]
resource_name = "fade_out"
length = 0.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("ColorRect:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_changer"]
_data = {
&"fade_in": SubResource("Animation_fade_in"),
&"fade_out": SubResource("Animation_fade_out")
}
[node name="SceneChanger" type="CanvasLayer" unique_id=506779040]
layer = 100
script = ExtResource("1_script")
[node name="ColorRect" type="ColorRect" parent="." unique_id=12093100]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0, 0, 0, 0)
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=505073843]
libraries/ = SubResource("AnimationLibrary_changer")
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
[ext_resource type="Script" uid="uid://dkplkt6q8e3b5" path="res://src/core/unit_controller.gd" id="4_unit_ctrl"] [ext_resource type="Script" uid="uid://dkplkt6q8e3b5" path="res://src/core/unit_controller.gd" id="4_unit_ctrl"]
[ext_resource type="PackedScene" uid="uid://dfsvswt2g4422" path="res://src/entities/monsters/zombie/zombie_monster.tscn" id="5_2uitn"] [ext_resource type="PackedScene" uid="uid://dfsvswt2g4422" path="res://src/entities/monsters/zombie/zombie_monster.tscn" id="5_2uitn"]
[ext_resource type="PackedScene" uid="uid://bqga1rvcjyydy" path="res://src/ui/hud.tscn" id="5_hud"] [ext_resource type="PackedScene" uid="uid://bqga1rvcjyydy" path="res://src/ui/hud.tscn" id="5_hud"]
[ext_resource type="PackedScene" path="res://src/entities/monsters/skeleton/skeleton_monster.tscn" id="6_skeleton"]
[sub_resource type="NavigationMesh" id="NavigationMesh_map"] [sub_resource type="NavigationMesh" id="NavigationMesh_map"]
agent_height = 1.0 agent_height = 1.0
...@@ -45,7 +47,7 @@ script = ExtResource("1_rts_cam") ...@@ -45,7 +47,7 @@ script = ExtResource("1_rts_cam")
[node name="StageManager" type="Node" parent="." unique_id=132524356] [node name="StageManager" type="Node" parent="." unique_id=132524356]
script = ExtResource("2_stage_mgr") script = ExtResource("2_stage_mgr")
monster_scenes = Array[PackedScene]([ExtResource("4_nxx65"), ExtResource("5_2uitn")]) monster_scenes = Array[PackedScene]([ExtResource("4_nxx65"), ExtResource("5_2uitn"), ExtResource("6_skeleton")])
[node name="UnitController" type="Control" parent="." unique_id=552898295] [node name="UnitController" type="Control" parent="." unique_id=552898295]
layout_mode = 3 layout_mode = 3
......
...@@ -101,6 +101,9 @@ func _on_spawn_timer_timeout() -> void: ...@@ -101,6 +101,9 @@ func _on_spawn_timer_timeout() -> void:
var scene_path: String = selected_scene.resource_path.to_lower() var scene_path: String = selected_scene.resource_path.to_lower()
if "zombie" in scene_path: if "zombie" in scene_path:
monster_id = "zombie" monster_id = "zombie"
elif "skeleton" in scene_path:
monster_id = "skeleton"
var monster_data: MonsterData = DataManager.get_stage_monster_data(monster_id, stage) var monster_data: MonsterData = DataManager.get_stage_monster_data(monster_id, stage)
if monster_data and monster_instance.has_method("initialize_monster"): if monster_data and monster_instance.has_method("initialize_monster"):
......
[gd_scene format=3]
[ext_resource type="PackedScene" path="res://assets/models/monsters/skeleton/skeleton.fbx" id="1_fbx"]
[ext_resource type="AnimationLibrary" path="res://assets/models/monsters/skeleton/skeleton_animations.tres" id="2_anims"]
[node name="skeleton" instance=ExtResource("1_fbx")]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0)
[node name="AnimationPlayer" parent="." index="1"]
libraries = {
"": ExtResource("2_anims")
}
class_name SkeletonMonster
extends BaseMonster
## Skeleton 전용 동작 및 비주얼 제어를 담당하는 클래스
func _setup_skin_and_animations() -> void:
_apply_skeleton_skin(_model_instance)
_model_anim_player = _find_animation_player(_model_instance)
if _model_anim_player:
print("SkeletonMonster: Linked model AnimationPlayer")
# 스켈레톤 애니메이션 라이브러리 동적 로드 및 등록
var m_name: String = "skeleton"
var anim_lib_path: String = "res://assets/models/monsters/" + m_name + "/" + m_name + "_animations.tres"
var path_to_load: String = ""
if ResourceLoader.exists(anim_lib_path):
path_to_load = anim_lib_path
if path_to_load.is_empty():
return
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("SkeletonMonster: Loaded and registered ", m_name, " animations library successfully.")
else:
print("SkeletonMonster: Animation library already registered on model under another name.")
# 초기 Idle 애니메이션 재생 시도
var init_idle: String = _resolve_anim_name(_model_anim_player, m_name, "Idle")
if init_idle != "":
_model_anim_player.play(init_idle)
print("SkeletonMonster: Playing initial Idle: ", init_idle)
## 몬스터 자식 메쉬에 skeleton_0.png 텍스처를 입히는 재귀 함수
func _apply_skeleton_skin(node: Node) -> void:
if node is MeshInstance3D:
var mesh_inst: MeshInstance3D = node as MeshInstance3D
var texture_path: String = "res://assets/models/monsters/skeleton/skeleton_0.png"
if ResourceLoader.exists(texture_path):
var texture: Texture2D = load(texture_path) as Texture2D
if texture:
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_skeleton_skin(child)
## Skeleton 걷는 애니메이션 갱신 제어
func _update_monster_animation() -> void:
if not _model_anim_player:
return
var anim_name: String = _resolve_anim_name(_model_anim_player, "skeleton", "Walking")
if anim_name != "":
var anim: Animation = _model_anim_player.get_animation(anim_name)
if anim:
anim.loop_mode = Animation.LOOP_LINEAR
if _last_anim_state != "walking":
_last_anim_state = "walking"
_model_anim_player.play(anim_name, -1, 1.4) # Skeleton은 속도가 빠르므로 1.4배속 재생
print("SkeletonMonster: Playing Walk animation: ", anim_name)
[gd_scene load_steps=4 format=3]
[ext_resource type="Script" path="res://src/entities/monsters/skeleton/skeleton_monster.gd" id="1_script"]
[ext_resource type="PackedScene" path="res://src/entities/monsters/skeleton/skeleton.tscn" id="2_skeleton"]
[sub_resource type="SphereShape3D" id="SphereShape3D_collision"]
radius = 0.6
[node name="SkeletonMonster" type="PathFollow3D"]
script = ExtResource("1_script")
[node name="skeleton" parent="." instance=ExtResource("2_skeleton")]
[node name="MonsterArea" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="MonsterArea"]
shape = SubResource("SphereShape3D_collision")
...@@ -48,7 +48,7 @@ func _ready() -> void: ...@@ -48,7 +48,7 @@ func _ready() -> void:
# 선택된 소환사 데이터가 존재하는지 검증 (디버그 모드 대안 포함) # 선택된 소환사 데이터가 존재하는지 검증 (디버그 모드 대안 포함)
if not GameManager.selected_summoner_data: if not GameManager.selected_summoner_data:
print("HUD: No summoner selected in GameManager. Redirecting to selection screen.") print("HUD: No summoner selected in GameManager. Redirecting to selection screen.")
get_tree().change_scene_to_file("res://src/ui/summoner_selection/summoner_selection.tscn") SceneChanger.change_scene_to_file("res://src/ui/summoner_selection/summoner_selection.tscn")
return return
# 소환사 데이터 초기 셋업 가동 # 소환사 데이터 초기 셋업 가동
......
...@@ -64,7 +64,7 @@ alignment = 1 ...@@ -64,7 +64,7 @@ alignment = 1
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
theme_override_font_sizes/font_size = 20 theme_override_font_sizes/font_size = 20
text = "SPAWN UNIT (100G)" text = "유닛 생성(100G)"
[node name="ResultPopup" type="Panel" parent="." unique_id=1545119054] [node name="ResultPopup" type="Panel" parent="." unique_id=1545119054]
visible = false visible = false
......
...@@ -48,7 +48,5 @@ func _on_select_warlock_pressed() -> void: ...@@ -48,7 +48,5 @@ func _on_select_warlock_pressed() -> void:
func _transition_to_main_game() -> void: func _transition_to_main_game() -> void:
print("SummonerSelection: Selected summoner: ", GameManager.selected_summoner_data.summoner_name) print("SummonerSelection: Selected summoner: ", GameManager.selected_summoner_data.summoner_name)
# 페이지 이동: 메인 게임 씬으로 씬 변경 # 페이지 이동: SceneChanger 트랜지션 시스템 활용
var err = get_tree().change_scene_to_file("res://src/core/main.tscn") SceneChanger.change_scene_to_file("res://src/core/main.tscn")
if err != OK:
print("SummonerSelection: Failed to transition to main.tscn: ", err)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment