添加 claude code game studios 到项目
This commit is contained in:
76
docs/engine-reference/godot/modules/animation.md
Normal file
76
docs/engine-reference/godot/modules/animation.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Godot Animation — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **IK system fully restored**: Complete inverse kinematics for 3D skeletons
|
||||
- CCDIK, FABRIK, Jacobian IK, Spline IK, TwoBoneIK
|
||||
- Applied via `SkeletonModifier3D` nodes (not the old IK approach)
|
||||
- **Animation editor QoL**: Solo/hide/lock/delete for Bezier node groups; draggable timeline
|
||||
|
||||
### 4.5 Changes
|
||||
- **BoneConstraint3D**: Bind bones to other bones with modifiers
|
||||
- `AimModifier3D`, `CopyTransformModifier3D`, `ConvertTransformModifier3D`
|
||||
|
||||
### 4.3 Changes (in training data)
|
||||
- **AnimationMixer**: Base class for both AnimationPlayer and AnimationTree
|
||||
- `method_call_mode` → `callback_mode_method`
|
||||
- `playback_active` → `active`
|
||||
- `bone_pose_updated` signal → `skeleton_updated`
|
||||
- **`Skeleton3D.add_bone()`**: Now returns `int32` (was `void`)
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### AnimationPlayer (unchanged API, new base class)
|
||||
```gdscript
|
||||
@onready var anim_player: AnimationPlayer = %AnimationPlayer
|
||||
|
||||
func play_attack() -> void:
|
||||
anim_player.play(&"attack")
|
||||
await anim_player.animation_finished
|
||||
```
|
||||
|
||||
### IK Setup (4.6 — NEW)
|
||||
```gdscript
|
||||
# Add SkeletonModifier3D-based IK nodes as children of Skeleton3D
|
||||
# Available types:
|
||||
# - SkeletonModifier3D (base)
|
||||
# - TwoBoneIK (arms, legs)
|
||||
# - FABRIK (chains, tentacles)
|
||||
# - CCDIK (tails, spines)
|
||||
# - Jacobian IK (complex multi-joint)
|
||||
# - Spline IK (along curves)
|
||||
|
||||
# Configure in editor or code:
|
||||
# 1. Add IK modifier node as child of Skeleton3D
|
||||
# 2. Set target bone and tip bone
|
||||
# 3. Add a Marker3D as the IK target
|
||||
# 4. IK solver runs automatically each frame
|
||||
```
|
||||
|
||||
### BoneConstraint3D (4.5 — NEW)
|
||||
```gdscript
|
||||
# Add as child of Skeleton3D
|
||||
# Types:
|
||||
# - AimModifier3D: Point bone at target
|
||||
# - CopyTransformModifier3D: Mirror another bone's transform
|
||||
# - ConvertTransformModifier3D: Remap transform values
|
||||
```
|
||||
|
||||
### AnimationTree (base class changed in 4.3)
|
||||
```gdscript
|
||||
# AnimationTree now extends AnimationMixer (not Node directly)
|
||||
# Use AnimationMixer properties:
|
||||
@onready var anim_tree: AnimationTree = %AnimationTree
|
||||
|
||||
func _ready() -> void:
|
||||
anim_tree.active = true # NOT playback_active (deprecated 4.3)
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Using `playback_active` instead of `active` (deprecated since 4.3)
|
||||
- Using `bone_pose_updated` signal instead of `skeleton_updated` (renamed in 4.3)
|
||||
- Using old IK approach instead of SkeletonModifier3D system (restored in 4.6)
|
||||
- Not checking `is AnimationMixer` when type-checking animation nodes
|
||||
79
docs/engine-reference/godot/modules/audio.md
Normal file
79
docs/engine-reference/godot/modules/audio.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Godot Audio — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
No major breaking changes to the audio API in 4.4–4.6. The core audio system
|
||||
remains stable. Key updates are workflow improvements:
|
||||
|
||||
### 4.6 Changes
|
||||
- **No audio-specific breaking changes** in this release
|
||||
|
||||
### 4.5 Changes
|
||||
- **No audio-specific breaking changes** in this release
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### Playing Audio
|
||||
```gdscript
|
||||
@onready var sfx_player: AudioStreamPlayer = %SFXPlayer
|
||||
@onready var music_player: AudioStreamPlayer = %MusicPlayer
|
||||
|
||||
func play_sfx(stream: AudioStream) -> void:
|
||||
sfx_player.stream = stream
|
||||
sfx_player.play()
|
||||
|
||||
func play_music(stream: AudioStream, fade_time: float = 1.0) -> void:
|
||||
var tween: Tween = create_tween()
|
||||
tween.tween_property(music_player, "volume_db", -80.0, fade_time)
|
||||
await tween.finished
|
||||
music_player.stream = stream
|
||||
music_player.volume_db = 0.0
|
||||
music_player.play()
|
||||
```
|
||||
|
||||
### 3D Spatial Audio
|
||||
```gdscript
|
||||
@onready var audio_3d: AudioStreamPlayer3D = %AudioPlayer3D
|
||||
|
||||
func _ready() -> void:
|
||||
audio_3d.max_distance = 50.0
|
||||
audio_3d.attenuation_model = AudioStreamPlayer3D.ATTENUATION_INVERSE_DISTANCE
|
||||
audio_3d.unit_size = 10.0
|
||||
```
|
||||
|
||||
### Audio Buses
|
||||
```gdscript
|
||||
# Set bus volumes
|
||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index(&"Music"), volume_db)
|
||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index(&"SFX"), volume_db)
|
||||
|
||||
# Mute a bus
|
||||
AudioServer.set_bus_mute(AudioServer.get_bus_index(&"Music"), true)
|
||||
```
|
||||
|
||||
### Object Pooling for SFX
|
||||
```gdscript
|
||||
# Pre-create multiple AudioStreamPlayer nodes for concurrent sounds
|
||||
var _sfx_pool: Array[AudioStreamPlayer] = []
|
||||
|
||||
func _ready() -> void:
|
||||
for i in range(8):
|
||||
var player := AudioStreamPlayer.new()
|
||||
player.bus = &"SFX"
|
||||
add_child(player)
|
||||
_sfx_pool.append(player)
|
||||
|
||||
func play_pooled(stream: AudioStream) -> void:
|
||||
for player in _sfx_pool:
|
||||
if not player.playing:
|
||||
player.stream = stream
|
||||
player.play()
|
||||
return
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Creating new AudioStreamPlayer nodes at runtime instead of pooling
|
||||
- Not using audio buses for volume categories (Music, SFX, UI, Voice)
|
||||
- Using `_process()` for audio timing instead of signals (`finished`)
|
||||
72
docs/engine-reference/godot/modules/input.md
Normal file
72
docs/engine-reference/godot/modules/input.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Godot Input — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **Dual-focus system**: Mouse/touch focus is now separate from keyboard/gamepad focus
|
||||
- Visual feedback differs by input method
|
||||
- Custom focus implementations may need updating
|
||||
- **Select Mode keybind changed**: "Select Mode" is now `v` key; old mode renamed "Transform Mode" (`q` key)
|
||||
|
||||
### 4.5 Changes
|
||||
- **SDL3 gamepad driver**: Gamepad handling delegated to SDL library for better cross-platform support
|
||||
- **Recursive Control disable**: Single property disables mouse/focus for entire node hierarchies
|
||||
|
||||
### 4.3 Changes (in training data)
|
||||
- **InputEventShortcut**: Dedicated event type for menu shortcuts (optional)
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### Input Actions (unchanged)
|
||||
```gdscript
|
||||
func _physics_process(delta: float) -> void:
|
||||
var input_dir: Vector2 = Input.get_vector(
|
||||
&"move_left", &"move_right", &"move_forward", &"move_back"
|
||||
)
|
||||
if Input.is_action_just_pressed(&"jump"):
|
||||
jump()
|
||||
```
|
||||
|
||||
### Input Events (unchanged)
|
||||
```gdscript
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
handle_click(event.position)
|
||||
elif event is InputEventKey:
|
||||
if event.keycode == KEY_ESCAPE and event.pressed:
|
||||
toggle_pause()
|
||||
```
|
||||
|
||||
### Focus Management (4.6 — CHANGED)
|
||||
```gdscript
|
||||
# Mouse/touch and keyboard/gamepad focus are now SEPARATE
|
||||
# Visual styles may differ depending on which input method is active
|
||||
# If you have custom focus drawing, test with both input methods
|
||||
|
||||
# Standard approach still works:
|
||||
func _ready() -> void:
|
||||
%StartButton.grab_focus() # Keyboard/gamepad focus
|
||||
|
||||
# But be aware: mouse hover focus != keyboard focus in 4.6
|
||||
```
|
||||
|
||||
### Gamepad (4.5+ — SDL3 backend)
|
||||
```gdscript
|
||||
# API unchanged, but SDL3 provides:
|
||||
# - Better device detection across platforms
|
||||
# - Improved rumble support
|
||||
# - More consistent button mapping
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventJoypadButton:
|
||||
if event.button_index == JOY_BUTTON_A and event.pressed:
|
||||
confirm_selection()
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Not testing both mouse and keyboard focus paths (dual-focus in 4.6)
|
||||
- Assuming `grab_focus()` affects mouse focus (it only affects keyboard/gamepad in 4.6)
|
||||
- Using string literals instead of `StringName` (`&"action"`) for action names in hot paths
|
||||
101
docs/engine-reference/godot/modules/navigation.md
Normal file
101
docs/engine-reference/godot/modules/navigation.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Godot Navigation — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.5 Changes
|
||||
- **Dedicated 2D navigation server**: No longer a proxy to 3D NavigationServer
|
||||
- Reduces export binary size for 2D-only games
|
||||
- API remains the same for both 2D and 3D
|
||||
|
||||
### 4.3 Changes (in training data)
|
||||
- **`NavigationRegion2D`**: Removed `avoidance_layers` and `constrain_avoidance` properties
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### NavigationAgent3D (Preferred for Most Cases)
|
||||
```gdscript
|
||||
@onready var nav_agent: NavigationAgent3D = %NavigationAgent3D
|
||||
|
||||
func _ready() -> void:
|
||||
nav_agent.path_desired_distance = 0.5
|
||||
nav_agent.target_desired_distance = 1.0
|
||||
nav_agent.velocity_computed.connect(_on_velocity_computed)
|
||||
|
||||
func navigate_to(target: Vector3) -> void:
|
||||
nav_agent.target_position = target
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if nav_agent.is_navigation_finished():
|
||||
return
|
||||
var next_pos: Vector3 = nav_agent.get_next_path_position()
|
||||
var direction: Vector3 = global_position.direction_to(next_pos)
|
||||
nav_agent.velocity = direction * move_speed
|
||||
|
||||
func _on_velocity_computed(safe_velocity: Vector3) -> void:
|
||||
velocity = safe_velocity
|
||||
move_and_slide()
|
||||
```
|
||||
|
||||
### NavigationAgent2D
|
||||
```gdscript
|
||||
@onready var nav_agent: NavigationAgent2D = %NavigationAgent2D
|
||||
|
||||
func navigate_to(target: Vector2) -> void:
|
||||
nav_agent.target_position = target
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if nav_agent.is_navigation_finished():
|
||||
return
|
||||
var next_pos: Vector2 = nav_agent.get_next_path_position()
|
||||
var direction: Vector2 = global_position.direction_to(next_pos)
|
||||
velocity = direction * move_speed
|
||||
move_and_slide()
|
||||
```
|
||||
|
||||
### Low-Level Path Query (3D)
|
||||
```gdscript
|
||||
# Direct server query for custom pathfinding logic
|
||||
var query := NavigationPathQueryParameters3D.new()
|
||||
query.map = get_world_3d().navigation_map
|
||||
query.start_position = global_position
|
||||
query.target_position = target_pos
|
||||
query.navigation_layers = navigation_layers
|
||||
|
||||
var result := NavigationPathQueryResult3D.new()
|
||||
NavigationServer3D.query_path(query, result)
|
||||
var path: PackedVector3Array = result.path
|
||||
```
|
||||
|
||||
### Avoidance
|
||||
```gdscript
|
||||
# Enable RVO2-based local avoidance
|
||||
nav_agent.avoidance_enabled = true
|
||||
nav_agent.radius = 0.5
|
||||
nav_agent.max_speed = move_speed
|
||||
nav_agent.neighbor_distance = 10.0
|
||||
|
||||
# Use velocity_computed signal for avoidance-safe movement
|
||||
nav_agent.velocity_computed.connect(_on_velocity_computed)
|
||||
|
||||
# Set velocity each frame (avoidance needs this)
|
||||
nav_agent.velocity = desired_velocity
|
||||
```
|
||||
|
||||
### Navigation Layers
|
||||
```gdscript
|
||||
# Use layers to separate walkable areas by agent type
|
||||
# Layer 1: Ground units
|
||||
# Layer 2: Flying units
|
||||
# Layer 3: Swimming units
|
||||
nav_agent.navigation_layers = 1 # Ground only
|
||||
nav_agent.navigation_layers = 1 | 2 # Ground + Flying
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Calling `get_next_path_position()` without checking `is_navigation_finished()`
|
||||
- Not setting `velocity` on the agent when avoidance is enabled (required for RVO2)
|
||||
- Using `NavigationRegion2D.avoidance_layers` (removed in 4.3)
|
||||
- Forgetting to bake navigation mesh after modifying geometry
|
||||
- Not setting `navigation_layers` (defaults to all layers)
|
||||
76
docs/engine-reference/godot/modules/networking.md
Normal file
76
docs/engine-reference/godot/modules/networking.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Godot Networking — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **Networking section in breaking changes**: See the official migration guide for
|
||||
specifics at the 4.5→4.6 level
|
||||
|
||||
### 4.5 Changes
|
||||
- **No major networking API breaks** — core multiplayer API remains stable
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### High-Level Multiplayer
|
||||
```gdscript
|
||||
# Server
|
||||
func host_game(port: int = 9999) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
peer.create_server(port)
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.peer_connected.connect(_on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
||||
|
||||
# Client
|
||||
func join_game(address: String, port: int = 9999) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
peer.create_client(address, port)
|
||||
multiplayer.multiplayer_peer = peer
|
||||
```
|
||||
|
||||
### RPCs
|
||||
```gdscript
|
||||
# Server-authoritative pattern
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func request_action(action_data: Dictionary) -> void:
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
# Validate on server, then broadcast
|
||||
_execute_action.rpc(action_data)
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func _execute_action(action_data: Dictionary) -> void:
|
||||
# All peers execute the validated action
|
||||
pass
|
||||
```
|
||||
|
||||
### MultiplayerSpawner and MultiplayerSynchronizer
|
||||
```gdscript
|
||||
# Use MultiplayerSpawner for automatic node replication
|
||||
# Use MultiplayerSynchronizer for property synchronization
|
||||
|
||||
# MultiplayerSynchronizer setup:
|
||||
# 1. Add as child of the node to sync
|
||||
# 2. Configure replication properties in editor
|
||||
# 3. Set visibility filters for relevancy
|
||||
```
|
||||
|
||||
### SceneMultiplayer Configuration
|
||||
```gdscript
|
||||
func _ready() -> void:
|
||||
var scene_mp := multiplayer as SceneMultiplayer
|
||||
scene_mp.auth_callback = _authenticate_peer
|
||||
scene_mp.server_relay = false # Direct peer connections
|
||||
|
||||
func _authenticate_peer(id: int, data: PackedByteArray) -> void:
|
||||
# Custom authentication logic
|
||||
pass
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Not using `"any_peer"` for client-to-server RPCs (defaults to authority only)
|
||||
- Trusting client data without server-side validation
|
||||
- Using `"unreliable"` for game state changes (use for position updates only)
|
||||
- Not setting multiplayer authority (`set_multiplayer_authority()`) on spawned nodes
|
||||
76
docs/engine-reference/godot/modules/physics.md
Normal file
76
docs/engine-reference/godot/modules/physics.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Godot Physics — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **Jolt Physics is the DEFAULT 3D engine** for new projects
|
||||
- Existing projects keep their current physics engine setting
|
||||
- Better determinism, stability, and performance than GodotPhysics3D
|
||||
- Some HingeJoint3D properties (`damp`) only work with GodotPhysics3D
|
||||
- 2D physics UNCHANGED (still Godot Physics 2D)
|
||||
|
||||
### 4.5 Changes
|
||||
- **3D physics interpolation rearchitected**: Moved from RenderingServer to SceneTree
|
||||
- User-facing API unchanged, but internal behavior may differ in edge cases
|
||||
|
||||
## Physics Engine Selection (4.6)
|
||||
|
||||
```
|
||||
Project Settings → Physics → 3D → Physics Engine:
|
||||
- Jolt Physics (DEFAULT for new projects)
|
||||
- GodotPhysics3D (legacy, still available)
|
||||
```
|
||||
|
||||
### Jolt vs GodotPhysics3D
|
||||
|
||||
| Feature | Jolt (default) | GodotPhysics3D |
|
||||
|---------|---------------|----------------|
|
||||
| Determinism | Better | Inconsistent |
|
||||
| Stability | Better | Adequate |
|
||||
| Performance | Better for complex scenes | Adequate |
|
||||
| HingeJoint3D `damp` | NOT supported | Supported |
|
||||
| Runtime warnings | Yes, for unsupported properties | No |
|
||||
| Collision margins | May behave differently | Original behavior |
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### Basic Physics Setup (unchanged)
|
||||
```gdscript
|
||||
# CharacterBody3D movement — API unchanged across engines
|
||||
extends CharacterBody3D
|
||||
|
||||
@export var speed: float = 5.0
|
||||
@export var jump_velocity: float = 4.5
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not is_on_floor():
|
||||
velocity += get_gravity() * delta
|
||||
|
||||
if Input.is_action_just_pressed("jump") and is_on_floor():
|
||||
velocity.y = jump_velocity
|
||||
|
||||
var input_dir: Vector2 = Input.get_vector("left", "right", "forward", "back")
|
||||
var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
|
||||
velocity.x = direction.x * speed
|
||||
velocity.z = direction.z * speed
|
||||
|
||||
move_and_slide()
|
||||
```
|
||||
|
||||
### Raycasting (unchanged)
|
||||
```gdscript
|
||||
var space_state: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
|
||||
var query := PhysicsRayQueryParameters3D.create(from, to)
|
||||
query.collision_mask = collision_mask
|
||||
var result: Dictionary = space_state.intersect_ray(query)
|
||||
if result:
|
||||
var hit_point: Vector3 = result.position
|
||||
var hit_normal: Vector3 = result.normal
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Assuming GodotPhysics3D is the default (Jolt since 4.6)
|
||||
- Using HingeJoint3D `damp` property without checking physics engine (Jolt ignores it)
|
||||
- Not testing collision edge cases when switching between physics engines
|
||||
59
docs/engine-reference/godot/modules/rendering.md
Normal file
59
docs/engine-reference/godot/modules/rendering.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Godot Rendering — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **D3D12 is the default rendering backend on Windows** (was Vulkan)
|
||||
- **Glow processes before tonemapping** (was after) — uses screen blending mode
|
||||
- **AgX tonemapper**: new white point and contrast controls
|
||||
- **SSR overhauled**: better realism, visual stability, and performance
|
||||
|
||||
### 4.5 Changes
|
||||
- **Shader Baker**: Pre-compiles shaders to reduce startup time
|
||||
- **SMAA 1x**: New anti-aliasing option (sharper than FXAA, cheaper than TAA)
|
||||
- **Stencil buffer support**: Enables selective geometry masking/portal effects
|
||||
- **Bent normal maps**: Directional occlusion encoded in normal map textures
|
||||
- **Specular occlusion**: Ambient occlusion now correctly affects reflections
|
||||
|
||||
### 4.4 Changes
|
||||
- **`RenderingDevice.draw_list_begin`**: Many parameters removed; optional `breadcrumb` added
|
||||
- **Shader texture types**: Changed from `Texture2D` to `Texture` base type
|
||||
- **Particles `.restart()`**: Added optional `keep_seed` parameter
|
||||
|
||||
### 4.3 Changes (in training data)
|
||||
- **Compositor node**: `Compositor` + `CompositorEffect` for post-processing chains
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### Post-Processing (4.3+)
|
||||
```gdscript
|
||||
# Use Compositor node — NOT manual viewport shader chains
|
||||
# Add Compositor as child of WorldEnvironment or Camera3D
|
||||
# Create CompositorEffect resources for each post-process step
|
||||
```
|
||||
|
||||
### Anti-Aliasing Options (4.6)
|
||||
```
|
||||
Project Settings → Rendering → Anti Aliasing:
|
||||
- MSAA 2D/3D: Hardware MSAA (quality but expensive)
|
||||
- Screen Space AA: FXAA (fast, blurry) or SMAA (sharp, moderate cost) # SMAA new in 4.5
|
||||
- TAA: Temporal (best quality, ghosting on fast motion)
|
||||
```
|
||||
|
||||
### Rendering Backend Selection (4.6)
|
||||
```
|
||||
Project Settings → Rendering → Renderer:
|
||||
- Forward+ (default): Full featured, desktop-focused
|
||||
- Mobile: Optimized for mobile/low-end, limited features
|
||||
- Compatibility: OpenGL 3.3 / WebGL 2, broadest hardware support
|
||||
|
||||
Windows default backend: D3D12 (was Vulkan pre-4.6)
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Assuming Vulkan is the default backend on Windows (D3D12 since 4.6)
|
||||
- Using manual viewport chains instead of Compositor for post-processing
|
||||
- Using `Texture2D` in shader uniform types (use `Texture` since 4.4)
|
||||
- Not using Shader Baker for projects with many shader variants
|
||||
82
docs/engine-reference/godot/modules/ui.md
Normal file
82
docs/engine-reference/godot/modules/ui.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Godot UI — Quick Reference
|
||||
|
||||
Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
## What Changed Since ~4.3 (LLM Cutoff)
|
||||
|
||||
### 4.6 Changes
|
||||
- **Dual-focus system**: Mouse/touch focus is now SEPARATE from keyboard/gamepad focus
|
||||
- Visual feedback differs by input method
|
||||
- Custom focus implementations may need updating
|
||||
- **TabContainer**: Tab properties editable directly in Inspector
|
||||
- **TileMapLayer scene tile rotation**: Scene tiles can be rotated like atlas tiles
|
||||
|
||||
### 4.5 Changes
|
||||
- **FoldableContainer**: New accordion-style UI node for collapsible sections
|
||||
- **Recursive Control behavior**: Disable mouse/focus for entire node hierarchies
|
||||
with a single property
|
||||
- **Screen reader support**: Control nodes work with AccessKit
|
||||
- **Live translation preview**: Test different locales in-editor
|
||||
- **`RichTextLabel.push_meta`**: Added optional `tooltip` parameter (from 4.4)
|
||||
|
||||
### 4.4 Changes
|
||||
- **`GraphEdit.connect_node`**: Added optional `keep_alive` parameter
|
||||
|
||||
## Current API Patterns
|
||||
|
||||
### Theme and Style (4.6)
|
||||
```gdscript
|
||||
# Editor uses new "Modern" theme by default
|
||||
# For game UI, use custom themes as before:
|
||||
var theme := Theme.new()
|
||||
theme.set_color(&"font_color", &"Label", Color.WHITE)
|
||||
theme.set_font_size(&"font_size", &"Label", 24)
|
||||
```
|
||||
|
||||
### Focus Management (4.6 — CHANGED)
|
||||
```gdscript
|
||||
# Keyboard/gamepad focus (grab_focus still works)
|
||||
func _ready() -> void:
|
||||
%StartButton.grab_focus()
|
||||
|
||||
# IMPORTANT: In 4.6, mouse hover is separate from keyboard focus
|
||||
# Both can be active simultaneously on different controls
|
||||
# Test your UI with BOTH mouse and keyboard/gamepad
|
||||
|
||||
# Focus neighbors (unchanged)
|
||||
%Button1.focus_neighbor_bottom = %Button2.get_path()
|
||||
%Button1.focus_neighbor_right = %Button3.get_path()
|
||||
```
|
||||
|
||||
### FoldableContainer (4.5 — NEW)
|
||||
```gdscript
|
||||
# Accordion-style collapsible container
|
||||
# Add as parent of content you want to make collapsible
|
||||
# Children show/hide when header is clicked
|
||||
# Configure via editor properties or code
|
||||
```
|
||||
|
||||
### Recursive Disable (4.5 — NEW)
|
||||
```gdscript
|
||||
# Disable all mouse/focus interactions for a hierarchy
|
||||
# Useful for disabling entire menu sections
|
||||
%SettingsPanel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
# In 4.5+, this can propagate recursively to children
|
||||
```
|
||||
|
||||
### Localization-Ready UI (best practice)
|
||||
```gdscript
|
||||
# Use tr() for all visible strings
|
||||
label.text = tr("MENU_START_GAME")
|
||||
|
||||
# Use auto-wrap for labels (text length varies by language)
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
|
||||
# Test with live translation preview in editor (4.5+)
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
- Assuming `grab_focus()` affects mouse focus (keyboard/gamepad only in 4.6)
|
||||
- Not testing UI with both mouse and gamepad after upgrading to 4.6
|
||||
- Hardcoding strings instead of using `tr()` for localization
|
||||
- Not using `FoldableContainer` for collapsible UI (new in 4.5, cleaner than custom)
|
||||
Reference in New Issue
Block a user