[gd_scene load_steps=3 format=3 uid="uid://char_creation_scene_sr"] [ext_resource type="Script" path="res://ui/character_creation.gd" id="1_charcreation"] ; #705: Character creation screen — 3D preview + 5-tab customisation panel. ; SubViewport renders CharacterVisual live. Tab panel: Body/Head/Hair/Clothing/Accessories. ; Keyboard: Q/E rotate, Tab/Shift+Tab cycle tabs, R randomize, Enter start, Esc back. ; D-146 (tile-scale preview), D-158 (frontal -5° camera default), D-155 (cardinal rotation). [sub_resource type="Environment" id="Environment_1"] background_mode = 1 background_color = Color(0.03, 0.03, 0.06, 1) ambient_light_source = 2 ambient_light_color = Color(0.4, 0.45, 0.55, 1) ambient_light_energy = 0.5 ; =========================================================================== ; Root ; =========================================================================== [node name="CharacterCreation" type="Control"] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 script = ExtResource("1_charcreation") [node name="Background" type="ColorRect" parent="."] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 color = Color(0.03, 0.03, 0.06, 1.0) mouse_filter = 2 ; =========================================================================== ; Main layout — fills screen except footer (48px at bottom) ; =========================================================================== [node name="Layout" type="HBoxContainer" parent="."] layout_mode = 1 anchor_right = 1.0 anchor_bottom = 1.0 offset_bottom = -48.0 theme_override_constants/separation = 0 ; =========================================================================== ; Preview panel (~60% of width): SubViewport + rotate/camera overlay buttons ; =========================================================================== [node name="PreviewPanel" type="Control" parent="Layout"] layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 3.0 ; SubViewportContainer fills the preview panel [node name="SubViewportContainer" type="SubViewportContainer" parent="Layout/PreviewPanel"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 stretch = true ; SubViewport: 3D scene for live character preview (ALWAYS update mode) [node name="SubViewport" type="SubViewport" parent="Layout/PreviewPanel/SubViewportContainer"] disable_3d = false size = Vector2i(540, 720) render_target_update_mode = 3 [node name="WorldEnvironment" type="WorldEnvironment" parent="Layout/PreviewPanel/SubViewportContainer/SubViewport"] environment = SubResource("Environment_1") ; Node3D anchor where CharacterVisual is parented at runtime [node name="CharacterVisualAnchor" type="Node3D" parent="Layout/PreviewPanel/SubViewportContainer/SubViewport"] ; Camera: frontal preset (-5° pitch, D-158). Script calls look_at() in _ready(). [node name="PreviewCamera" type="Camera3D" parent="Layout/PreviewPanel/SubViewportContainer/SubViewport"] position = Vector3(0, 1.11, 2.39) rotation = Vector3(-0.0873, 0, 0) current = true fov = 40.0 ; Key light: upper-left-front [node name="PreviewLight" type="DirectionalLight3D" parent="Layout/PreviewPanel/SubViewportContainer/SubViewport"] transform = Transform3D(0.866, -0.354, 0.354, 0, 0.707, 0.707, -0.5, -0.612, 0.612, 2, 3, 2) light_energy = 1.2 shadow_enabled = true ; Fill light: right side, softer [node name="FillLight" type="DirectionalLight3D" parent="Layout/PreviewPanel/SubViewportContainer/SubViewport"] transform = Transform3D(0.866, -0.259, -0.428, 0, 0.856, -0.517, 0.5, 0.448, 0.741, -2, 2, -1) light_energy = 0.4 ; Overlay: rotate buttons and camera angle button — sits on top of the SubViewportContainer ; mouse_filter=PASS so overlay receives input but passes through clicks to elements behind [node name="PreviewOverlay" type="Control" parent="Layout/PreviewPanel"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 ; Camera angle toggle — top-left corner [node name="CamAngleBtn" type="Button" parent="Layout/PreviewPanel/PreviewOverlay"] layout_mode = 1 anchor_right = 0.0 anchor_bottom = 0.0 offset_right = 80.0 offset_bottom = 28.0 text = "Dramatic" theme_override_font_sizes/font_size = 11 theme_override_colors/font_color = Color(0.53, 0.56, 0.63, 1.0) ; Rotate buttons — bottom-center of preview panel [node name="RotateButtons" type="HBoxContainer" parent="Layout/PreviewPanel/PreviewOverlay"] layout_mode = 1 anchor_left = 0.5 anchor_top = 1.0 anchor_right = 0.5 anchor_bottom = 1.0 offset_left = -70.0 offset_top = -36.0 offset_right = 70.0 offset_bottom = -8.0 grow_horizontal = 2 grow_vertical = 0 alignment = 1 theme_override_constants/separation = 8 [node name="RotateLeftBtn" type="Button" parent="Layout/PreviewPanel/PreviewOverlay/RotateButtons"] layout_mode = 2 custom_minimum_size = Vector2(60, 28) text = "[Q] ◄" theme_override_font_sizes/font_size = 12 theme_override_colors/font_color = Color(0.784, 0.816, 0.878, 1.0) [node name="RotateRightBtn" type="Button" parent="Layout/PreviewPanel/PreviewOverlay/RotateButtons"] layout_mode = 2 custom_minimum_size = Vector2(60, 28) text = "► [E]" theme_override_font_sizes/font_size = 12 theme_override_colors/font_color = Color(0.784, 0.816, 0.878, 1.0) ; Tab panel built programmatically in character_creation.gd _ready() ; (TabContainer defined in .tscn vanishes during child instantiation in Godot 4.6) ; =========================================================================== ; Footer — full width, 48px tall, anchored to bottom ; =========================================================================== [node name="Footer" type="HBoxContainer" parent="."] layout_mode = 1 anchor_left = 0.0 anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 offset_top = -48.0 grow_vertical = 0 theme_override_constants/separation = 8 [node name="BackBtn" type="Button" parent="Footer"] layout_mode = 2 custom_minimum_size = Vector2(120, 36) text = "[ESC] Back" theme_override_font_sizes/font_size = 13 theme_override_colors/font_color = Color(0.53, 0.56, 0.63, 1.0) [node name="FooterSpacer" type="Control" parent="Footer"] layout_mode = 2 size_flags_horizontal = 3 [node name="RandomizeBtn" type="Button" parent="Footer"] layout_mode = 2 custom_minimum_size = Vector2(140, 36) text = "[R] Randomize" theme_override_font_sizes/font_size = 13 theme_override_colors/font_color = Color(0.784, 0.816, 0.878, 1.0) [node name="StartBtn" type="Button" parent="Footer"] layout_mode = 2 custom_minimum_size = Vector2(140, 36) text = "[ENTER] Start" theme_override_font_sizes/font_size = 13 theme_override_colors/font_color = Color(0.906, 0.773, 0.278, 1.0) ; =========================================================================== ; Color picker modal — hidden by default, shown over right panel when swatch clicked ; =========================================================================== [node name="ColorPickerModal" type="Control" parent="."] layout_mode = 1 anchor_left = 0.6 anchor_top = 0.0 anchor_right = 1.0 anchor_bottom = 1.0 visible = false z_index = 10