Files
settled-reach/client/scenes/character_creation.tscn
T
jpmschweitzerandClaude Opus 4.6 2614c3c57a fix(client): build tab panel entirely in code — remove from .tscn
TabContainer and its VBoxContainer parent vanish during scene
instantiation when loaded as a child of MainMenu in Godot 4.6.
Moving the entire tab panel construction to _ready() resolves
the issue — the .tscn now only defines the preview side and footer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 19:11:37 +01:00

198 lines
6.9 KiB
Plaintext

[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