添加 claude code game studios 到项目

This commit is contained in:
panw
2026-05-15 14:52:29 +08:00
parent dff559462d
commit a16fe4bff7
415 changed files with 78609 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# Engine Reference Documentation
This directory contains curated, version-pinned documentation snapshots for the
game engine(s) used in this project. These files exist because **LLM knowledge
has a cutoff date** and game engines update frequently.
## Why This Exists
Claude's training data has a knowledge cutoff (currently May 2025). Game engines
like Godot, Unity, and Unreal ship updates that introduce breaking API changes,
new features, and deprecated patterns. Without these reference files, agents will
suggest outdated code.
## Structure
Each engine gets its own directory:
```
<engine>/
├── VERSION.md # Pinned version, verification date, knowledge gap window
├── breaking-changes.md # API changes between versions, organized by risk level
├── deprecated-apis.md # "Don't use X → Use Y" lookup tables
├── current-best-practices.md # New practices not in model training data
└── modules/ # Per-subsystem quick references (~150 lines max each)
├── rendering.md
├── physics.md
└── ...
```
## How Agents Use These Files
Engine-specialist agents are instructed to:
1. Read `VERSION.md` to confirm the current engine version
2. Check `deprecated-apis.md` before suggesting any engine API
3. Consult `breaking-changes.md` for version-specific concerns
4. Read relevant `modules/*.md` for subsystem-specific work
## Maintenance
### When to Update
- After upgrading the engine version
- When the LLM model is updated (new knowledge cutoff)
- After running `/refresh-docs` (if available)
- When you discover an API the model gets wrong
### How to Update
1. Update `VERSION.md` with the new engine version and date
2. Add new entries to `breaking-changes.md` for the version transition
3. Move newly deprecated APIs into `deprecated-apis.md`
4. Update `current-best-practices.md` with new patterns
5. Update relevant `modules/*.md` with API changes
6. Set "Last verified" dates on all modified files
### Quality Rules
- Every file must have a "Last verified: YYYY-MM-DD" date
- Keep module files under 150 lines (context budget)
- Include code examples showing correct/incorrect patterns
- Link to official documentation URLs for verification
- Only document things that differ from the model's training data

View File

@@ -0,0 +1,31 @@
# Godot Engine — Version Reference
| Field | Value |
|-------|-------|
| **Engine Version** | Godot 4.6 |
| **Release Date** | January 2026 |
| **Project Pinned** | 2026-02-12 |
| **Last Docs Verified** | 2026-02-12 |
| **LLM Knowledge Cutoff** | May 2025 |
## Knowledge Gap Warning
The LLM's training data likely covers Godot up to ~4.3. Versions 4.4, 4.5,
and 4.6 introduced significant changes that the model does NOT know about.
Always cross-reference this directory before suggesting Godot API calls.
## Post-Cutoff Version Timeline
| Version | Release | Risk Level | Key Theme |
|---------|---------|------------|-----------|
| 4.4 | ~Mid 2025 | MEDIUM | Jolt physics option, FileAccess return types, shader texture type changes |
| 4.5 | ~Late 2025 | HIGH | Accessibility (AccessKit), variadic args, @abstract, shader baker, SMAA |
| 4.6 | Jan 2026 | HIGH | Jolt default, glow rework, D3D12 default on Windows, IK restored |
## Verified Sources
- Official docs: https://docs.godotengine.org/en/stable/
- 4.5→4.6 migration: https://docs.godotengine.org/en/stable/tutorials/migrating/upgrading_to_godot_4.6.html
- 4.4→4.5 migration: https://docs.godotengine.org/en/stable/tutorials/migrating/upgrading_to_godot_4.5.html
- Changelog: https://github.com/godotengine/godot/blob/master/CHANGELOG.md
- Release notes: https://godotengine.org/releases/4.6/

View File

@@ -0,0 +1,70 @@
# Godot — Breaking Changes
Last verified: 2026-02-12
Changes between Godot versions, focused on post-LLM-cutoff changes (4.4+).
## 4.5 → 4.6 (Jan 2026 — POST-CUTOFF, HIGH RISK)
| Subsystem | Change | Details |
|-----------|--------|---------|
| Physics | Jolt is now the DEFAULT 3D physics engine | New projects use Jolt automatically. Existing projects keep their setting. Some HingeJoint3D properties (like `damp`) only work with GodotPhysics. |
| Rendering | Glow processes BEFORE tonemapping | Was after tonemapping. Scenes with glow will look different. Adjust intensity/blend in WorldEnvironment. |
| Rendering | D3D12 default on Windows | Was Vulkan. For better driver compatibility. |
| Rendering | AgX tonemapper new controls | White point and contrast parameters added. |
| Core | Quaternion initializes to identity | Was zero. Unlikely to affect most code but technically breaking. |
| UI | Dual-focus system | Mouse/touch focus now separate from keyboard/gamepad focus. Visual feedback differs by input method. |
| Animation | IK system fully restored | CCDIK, FABRIK, Jacobian IK, Spline IK, TwoBoneIK via SkeletonModifier3D nodes. |
| Editor | New "Modern" theme default | Grayscale replaces blue-tint. Restore: Editor Settings → Interface → Theme → Style: Classic |
| Editor | "Select Mode" keybind changed | New "Select Mode" (v key) prevents accidental transforms. Old mode renamed "Transform Mode" (q key). |
| 2D | TileMapLayer scene tile rotation | Scene tiles can now be rotated like atlas tiles. |
| Localization | CSV plural form support | No longer requires Gettext for plurals. Context columns added. |
| C# | Automatic string extraction | Translation strings auto-extracted from C# code. |
| Plugins | New EditorDock class | Specialized container for plugin docks with layout control. |
## 4.4 → 4.5 (Late 2025 — POST-CUTOFF, HIGH RISK)
| Subsystem | Change | Details |
|-----------|--------|---------|
| GDScript | Variadic arguments added | Functions can accept `...` arbitrary params — new language feature |
| GDScript | `@abstract` decorator | Abstract classes and methods now enforceable |
| GDScript | Script backtracing | Detailed call stacks available even in Release builds |
| Rendering | Stencil buffer support | New capability for advanced visual effects |
| Rendering | SMAA 1x antialiasing | New post-processing AA option |
| Rendering | Shader Baker | Pre-compiles shaders — reportedly 20x faster startup on some demos |
| Rendering | Bent normal maps, specular occlusion | New material features |
| Accessibility | Screen reader support | Control nodes work with accessibility tools via AccessKit |
| Editor | Live translation preview | Test GUI layouts in different languages in-editor |
| Physics | 3D interpolation rearchitected | Moved from RenderingServer to SceneTree. API unchanged but internals differ. |
| Animation | BoneConstraint3D | New: AimModifier3D, CopyTransformModifier3D, ConvertTransformModifier3D |
| Resources | `duplicate_deep()` added | New explicit method for deep duplication of nested resources |
| Navigation | Dedicated 2D navigation server | No longer a proxy to 3D navigation; smaller export for 2D games |
| UI | FoldableContainer node | New accordion-style container for collapsible UI sections |
| UI | Recursive Control behavior | Disable mouse/focus interactions across entire node hierarchies |
| Platform | visionOS export support | New platform target |
| Platform | SDL3 gamepad driver | Delegated gamepad handling to SDL library |
| Platform | Android 16KB page support | Required for Google Play targeting Android 15+ |
## 4.3 → 4.4 (Mid 2025 — NEAR CUTOFF, VERIFY)
| Subsystem | Change | Details |
|-----------|--------|---------|
| Core | `FileAccess.store_*` return `bool` | Was `void`. Methods: `store_8`, `store_16`, `store_32`, `store_64`, `store_buffer`, `store_csv_line`, `store_double`, `store_float`, `store_half`, `store_line`, `store_pascal_string`, `store_real`, `store_string`, `store_var` |
| Core | `OS.execute_with_pipe` | Added optional `blocking` parameter |
| Core | `RegEx.compile/create_from_string` | Added optional `show_error` parameter |
| Rendering | `RenderingDevice.draw_list_begin` | Many parameters removed; `breadcrumb` parameter added |
| Rendering | Shader texture types | Parameter/return types changed from `Texture2D` to `Texture` |
| Particles | `.restart()` method | Added optional `keep_seed` parameter (CPU/GPU 2D/3D) |
| GUI | `RichTextLabel.push_meta` | Added optional `tooltip` parameter |
| GUI | `GraphEdit.connect_node` | Added optional `keep_alive` parameter |
## 4.2 → 4.3 (In Training Data — LOW RISK)
| Subsystem | Change | Details |
|-----------|--------|---------|
| Animation | `Skeleton3D.add_bone` returns `int32` | Was `void` |
| Animation | `bone_pose_updated` signal | Replaced by `skeleton_updated` |
| TileMap | `TileMapLayer` replaces `TileMap` | One node per layer instead of multi-layer single node |
| Navigation | `NavigationRegion2D` | Removed `avoidance_layers`, `constrain_avoidance` properties |
| Editor | `EditorSceneFormatImporterFBX` | Renamed to `EditorSceneFormatImporterFBX2GLTF` |
| Animation | AnimationMixer base class | AnimationPlayer and AnimationTree now extend AnimationMixer |

View File

@@ -0,0 +1,107 @@
# Godot — Current Best Practices
Last verified: 2026-02-12 | Engine: Godot 4.6
Practices that are **new or changed** since the model's training data (~4.3).
This supplements (not replaces) the agent's built-in knowledge.
## GDScript (4.5+)
- **Variadic arguments**: Functions can accept arbitrary parameter counts
```gdscript
func log_values(prefix: String, values: Variant...) -> void:
for v in values:
print(prefix, ": ", v)
```
- **Abstract classes and methods**: Use `@abstract` to enforce inheritance
```gdscript
@abstract
class_name BaseEnemy extends CharacterBody3D
@abstract
func get_attack_pattern() -> Array[Attack]:
pass # Subclasses MUST override
```
- **Script backtracing**: Detailed call stacks available even in Release builds
## Physics (4.6)
- **Jolt Physics is the default 3D engine** for new projects
- Better determinism and stability than GodotPhysics3D
- Some HingeJoint3D properties (`damp`) only work with GodotPhysics
- Switch: Project Settings → Physics → 3D → Physics Engine
- 2D physics unchanged (still Godot Physics 2D)
## Rendering (4.6)
- **D3D12 is the default backend on Windows** (was Vulkan) — for better driver compatibility
- **Glow now processes before tonemapping** with screen blending mode — existing glow setups may look different
- **SSR overhauled** — significant improvement in realism, stability, and performance
- **AgX tonemapper** — new white point and contrast controls
## Rendering (4.5)
- **Shader Baker**: Pre-compile shaders to eliminate startup hitching
- **SMAA 1x**: New AA option — sharper than FXAA, cheaper than TAA
- **Stencil buffer**: Available for advanced masking/portal effects
- **Bent normal maps**: Directional occlusion in normal map textures
- **Specular occlusion**: Ambient occlusion now affects reflections
## Accessibility (4.5+)
- **Screen reader support**: Control nodes integrate with accessibility tools via AccessKit
- **Live translation preview**: Test GUI layouts in different languages directly in-editor
- **FoldableContainer**: New accordion-style UI node for collapsible sections
- **Recursive Control disable**: Disable mouse/focus interactions for entire node hierarchies with a single property
## Animation (4.5+)
- **BoneConstraint3D**: Bind bones to other bones with modifiers
- AimModifier3D, CopyTransformModifier3D, ConvertTransformModifier3D
## Animation (4.6)
- **IK system fully restored**: Complete inverse kinematics reintroduced for 3D
- Available modifiers: CCDIK, FABRIK, Jacobian IK, Spline IK, TwoBoneIK
- Applied via `SkeletonModifier3D` nodes
## Resources (4.5+)
- **`duplicate_deep()`**: Explicit deep duplication for nested resource trees
- Old `duplicate()` behavior retained for backward compatibility
- Use `duplicate_deep()` when you need per-instance copies of nested resources
## Navigation (4.5+)
- **Dedicated 2D navigation server**: No longer proxied through 3D NavigationServer
- Reduces export binary size for 2D-only games
## UI (4.6)
- **Dual-focus system**: Mouse/touch focus is now separate from keyboard/gamepad focus
- Visual feedback differs depending on input method
- Consider this when designing custom focus behavior
## Editor Workflow (4.6)
- Flexible dock drag-and-drop with blue outline preview (including bottom panel)
- Most panels support floating windows (except Debugger)
- New keyboard shortcuts: Alt+O (Output), Alt+S (Shader)
- Export variable auto-generation: drag resource from FileSystem into script editor
- Live preview in Quick Open dialog when "Live Preview" enabled
- New "Select Mode" (v key) prevents accidental transforms; old mode renamed "Transform Mode" (q key)
## Tooling
- **ripgrep has no `gdscript` type**: `*.gd` is registered under `gap` (GAP programming language).
`rg --type gdscript` is a hard error — the search never executes.
Always use `rg --glob "*.gd"` (shell) or `glob: "*.gd"` (Grep tool) to filter GDScript files.
## Platform (4.5+)
- **visionOS export**: First new platform since open-sourcing (windowed app mode)
- **SDL3 gamepad driver**: Better cross-platform gamepad support
- **Android**: Edge-to-edge display, camera feed access, 16KB page support (Android 15+)
- **Linux**: Wayland subwindow support for multi-window capability

View File

@@ -0,0 +1,43 @@
# Godot — Deprecated APIs
Last verified: 2026-02-12
If an agent suggests any API in the "Deprecated" column, it MUST be replaced
with the "Use Instead" column.
## Nodes & Classes
| Deprecated | Use Instead | Since | Notes |
|------------|-------------|-------|-------|
| `TileMap` | `TileMapLayer` | 4.3 | One node per layer instead of multi-layer node |
| `VisibilityNotifier2D` | `VisibleOnScreenNotifier2D` | 4.0 | Renamed for clarity |
| `VisibilityNotifier3D` | `VisibleOnScreenNotifier3D` | 4.0 | Renamed for clarity |
| `YSort` | `Node2D.y_sort_enabled` | 4.0 | Property on Node2D, not a separate node |
| `Navigation2D` / `Navigation3D` | `NavigationServer2D` / `NavigationServer3D` | 4.0 | Server-based API |
| `EditorSceneFormatImporterFBX` | `EditorSceneFormatImporterFBX2GLTF` | 4.3 | Renamed |
## Methods & Properties
| Deprecated | Use Instead | Since | Notes |
|------------|-------------|-------|-------|
| `yield()` | `await signal` | 4.0 | GDScript 2.0 coroutine syntax |
| `connect("signal", obj, "method")` | `signal.connect(callable)` | 4.0 | Callable-based connections |
| `instance()` | `instantiate()` | 4.0 | Renamed |
| `PackedScene.instance()` | `PackedScene.instantiate()` | 4.0 | Renamed |
| `get_world()` | `get_world_3d()` | 4.0 | Explicit 2D/3D split |
| `OS.get_ticks_msec()` | `Time.get_ticks_msec()` | 4.0 | Time singleton preferred |
| `duplicate()` for nested resources | `duplicate_deep()` | 4.5 | Explicit deep copy control |
| `Skeleton3D` signal `bone_pose_updated` | `skeleton_updated` | 4.3 | Renamed |
| `AnimationPlayer.method_call_mode` | `AnimationMixer.callback_mode_method` | 4.3 | Moved to base class |
| `AnimationPlayer.playback_active` | `AnimationMixer.active` | 4.3 | Moved to base class |
## Patterns (Not Just APIs)
| Deprecated Pattern | Use Instead | Why |
|--------------------|-------------|-----|
| String-based `connect()` | Typed signal connections | Type-safe, refactor-friendly |
| `$NodePath` in `_process()` | `@onready var` cached reference | Performance: path lookup every frame |
| Untyped `Array` / `Dictionary` | `Array[Type]`, typed variables | GDScript compiler optimizations |
| `Texture2D` in shader parameters | `Texture` base type | Changed in 4.4 |
| Manual post-process viewport chains | `Compositor` + `CompositorEffect` | Structured post-processing (4.3+) |
| GodotPhysics3D for new projects | Jolt Physics 3D | Default since 4.6; better stability |

View 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

View 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.44.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`)

View 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

View 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)

View 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

View 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

View 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

View 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)

View File

@@ -0,0 +1,250 @@
# Unity 6.3 LTS — Optional Packages & Systems
**Last verified:** 2026-02-13
This document indexes **optional packages and systems** available in Unity 6.3 LTS.
These are NOT part of the core engine but are commonly used for specific game types.
---
## How to Use This Guide
**✅ Detailed Documentation Available** - See `plugins/` directory for comprehensive guides
**🟡 Brief Overview Only** - Links to official docs, use WebSearch for details
**⚠️ Preview** - May have breaking changes in future versions
**📦 Package Required** - Install via Package Manager
---
## Production-Ready Packages (Detailed Docs Available)
### ✅ Cinemachine
- **Purpose:** Virtual camera system (dynamic cameras, cutscenes, camera blending)
- **When to use:** 3rd person games, cinematics, complex camera behavior
- **Knowledge Gap:** Cinemachine 3.0+ (Unity 6) has major API changes vs 2.x
- **Status:** Production-Ready
- **Package:** `com.unity.cinemachine` (Package Manager)
- **Detailed Docs:** [plugins/cinemachine.md](plugins/cinemachine.md)
- **Official:** https://docs.unity3d.com/Packages/com.unity.cinemachine@3.0/manual/index.html
---
### ✅ Addressables
- **Purpose:** Advanced asset management (async loading, remote content, memory control)
- **When to use:** Large projects, DLC, remote content delivery
- **Knowledge Gap:** Unity 6 improvements, better performance
- **Status:** Production-Ready
- **Package:** `com.unity.addressables` (Package Manager)
- **Detailed Docs:** [plugins/addressables.md](plugins/addressables.md)
- **Official:** https://docs.unity3d.com/Packages/com.unity.addressables@2.0/manual/index.html
---
### ✅ DOTS / Entities (ECS)
- **Purpose:** Data-Oriented Technology Stack (high-performance ECS for massive scale)
- **When to use:** Games with 1000s of entities, RTS, simulations
- **Knowledge Gap:** Entities 1.3+ (Unity 6) is production-ready, major rewrite from 0.x
- **Status:** Production-Ready (as of Unity 6.3 LTS)
- **Package:** `com.unity.entities` (Package Manager)
- **Detailed Docs:** [plugins/dots-entities.md](plugins/dots-entities.md)
- **Official:** https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html
---
## Other Production-Ready Packages (Brief Overview)
### 🟡 Input System (Already Covered)
- **Purpose:** Modern input handling (rebindable, cross-platform)
- **Status:** Production-Ready (default in Unity 6)
- **Package:** `com.unity.inputsystem`
- **Docs:** See [modules/input.md](../modules/input.md)
- **Official:** https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/index.html
---
### 🟡 UI Toolkit (Already Covered)
- **Purpose:** Modern runtime UI (HTML/CSS-like, performant)
- **Status:** Production-Ready (Unity 6)
- **Package:** Built-in
- **Docs:** See [modules/ui.md](../modules/ui.md)
- **Official:** https://docs.unity3d.com/Packages/com.unity.ui@2.0/manual/index.html
---
### 🟡 Visual Effect Graph (VFX Graph)
- **Purpose:** GPU-accelerated particle system (millions of particles)
- **When to use:** Large-scale VFX, fire, smoke, magic, explosions
- **Status:** Production-Ready
- **Package:** `com.unity.visualeffectgraph` (URP/HDRP only)
- **Official:** https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@17.0/manual/index.html
---
### 🟡 Shader Graph
- **Purpose:** Visual shader editor (node-based shader creation)
- **When to use:** Custom shaders without HLSL coding
- **Status:** Production-Ready
- **Package:** `com.unity.shadergraph` (URP/HDRP)
- **Official:** https://docs.unity3d.com/Packages/com.unity.shadergraph@17.0/manual/index.html
---
### 🟡 Timeline
- **Purpose:** Cinematic sequencing (cutscenes, scripted events)
- **When to use:** Story-driven games, cinematics, scripted sequences
- **Status:** Production-Ready
- **Package:** `com.unity.timeline` (built-in)
- **Official:** https://docs.unity3d.com/Packages/com.unity.timeline@1.8/manual/index.html
---
### 🟡 Animation Rigging
- **Purpose:** Runtime IK, procedural animation
- **When to use:** Foot IK, aim offsets, procedural limb placement
- **Status:** Production-Ready (Unity 6)
- **Package:** `com.unity.animation.rigging`
- **Official:** https://docs.unity3d.com/Packages/com.unity.animation.rigging@1.3/manual/index.html
---
### 🟡 ProBuilder
- **Purpose:** In-editor 3D modeling (level prototyping, greyboxing)
- **When to use:** Rapid prototyping, level blockout
- **Status:** Production-Ready
- **Package:** `com.unity.probuilder`
- **Official:** https://docs.unity3d.com/Packages/com.unity.probuilder@6.0/manual/index.html
---
### 🟡 Netcode for GameObjects
- **Purpose:** Official Unity multiplayer networking
- **When to use:** Multiplayer games (client-server architecture)
- **Status:** Production-Ready
- **Package:** `com.unity.netcode.gameobjects`
- **Official:** https://docs-multiplayer.unity3d.com/netcode/current/about/
---
### 🟡 Burst Compiler
- **Purpose:** LLVM-based compiler for C# Jobs (massive performance boost)
- **When to use:** Performance-critical code, DOTS, Jobs System
- **Status:** Production-Ready
- **Package:** `com.unity.burst` (auto-installed with DOTS)
- **Official:** https://docs.unity3d.com/Packages/com.unity.burst@1.8/manual/index.html
---
### 🟡 Jobs System
- **Purpose:** Multi-threaded job scheduling (CPU parallelism)
- **When to use:** Performance optimization, parallel processing
- **Status:** Production-Ready
- **Package:** Built-in
- **Official:** https://docs.unity3d.com/Manual/JobSystem.html
---
### 🟡 Mathematics
- **Purpose:** SIMD math library (optimized for Burst)
- **When to use:** DOTS, high-performance math
- **Status:** Production-Ready
- **Package:** `com.unity.mathematics`
- **Official:** https://docs.unity3d.com/Packages/com.unity.mathematics@1.3/manual/index.html
---
### 🟡 ML-Agents (Machine Learning)
- **Purpose:** Train AI with reinforcement learning
- **When to use:** Advanced AI training, procedural behavior
- **Status:** Production-Ready
- **Package:** `com.unity.ml-agents`
- **Official:** https://github.com/Unity-Technologies/ml-agents
---
### 🟡 Recorder
- **Purpose:** Capture gameplay footage, screenshots, animation clips
- **When to use:** Trailers, replays, debug recording
- **Status:** Production-Ready
- **Package:** `com.unity.recorder`
- **Official:** https://docs.unity3d.com/Packages/com.unity.recorder@5.0/manual/index.html
---
## Preview/Experimental Packages (Use with Caution)
### ⚠️ Splines
- **Purpose:** Runtime spline creation and editing
- **When to use:** Roads, paths, procedural content
- **Status:** Production-Ready (Unity 6)
- **Package:** `com.unity.splines`
- **Official:** https://docs.unity3d.com/Packages/com.unity.splines@2.6/manual/index.html
---
### ⚠️ Muse (AI Assistant)
- **Purpose:** AI-powered asset creation (textures, sprites, animations)
- **Status:** Preview (Unity 6)
- **Package:** `com.unity.muse.*`
- **Official:** https://unity.com/products/muse
---
### ⚠️ Sentis (Neural Network Inference)
- **Purpose:** Run neural networks in Unity (AI inference)
- **Status:** Preview
- **Package:** `com.unity.sentis`
- **Official:** https://docs.unity3d.com/Packages/com.unity.sentis@2.0/manual/index.html
---
## Deprecated Packages (Avoid for New Projects)
### ❌ UGUI (Canvas UI)
- **Deprecated:** Still supported, but UI Toolkit recommended
- **Use Instead:** UI Toolkit
---
### ❌ Legacy Particle System
- **Deprecated:** Use Visual Effect Graph (VFX Graph)
- **Use Instead:** VFX Graph
---
### ❌ Legacy Animation
- **Deprecated:** Use Animator (Mecanim)
- **Use Instead:** Animator Controller
---
## On-Demand WebSearch Strategy
For packages NOT listed above, use the following approach when users ask:
1. **WebSearch** for latest documentation: `"Unity 6.3 [package name]"`
2. Verify if package is:
- Post-cutoff (beyond May 2025 training data)
- Preview vs Production-Ready
- Still supported in Unity 6.3 LTS
3. Optionally cache findings in `plugins/[package-name].md` for future reference
---
## Quick Decision Guide
**I need virtual cameras****Cinemachine**
**I need async asset loading / DLC****Addressables**
**I need 1000s of entities (RTS, sim)****DOTS/Entities**
**I need modern input****Input System** (see modules/input.md)
**I need GPU particles****Visual Effect Graph**
**I need visual shaders****Shader Graph**
**I need cinematics****Timeline**
**I need runtime IK****Animation Rigging**
**I need level prototyping****ProBuilder**
**I need multiplayer****Netcode for GameObjects**
---
**Last Updated:** 2026-02-13
**Engine Version:** Unity 6.3 LTS
**LLM Knowledge Cutoff:** May 2025

View File

@@ -0,0 +1,57 @@
# Unity Engine — Version Reference
| Field | Value |
|-------|-------|
| **Engine Version** | Unity 6.3 LTS |
| **Release Date** | December 2025 |
| **Project Pinned** | 2026-02-13 |
| **Last Docs Verified** | 2026-02-13 |
| **LLM Knowledge Cutoff** | May 2025 |
## Knowledge Gap Warning
The LLM's training data likely covers Unity up to ~2022 LTS (2022.3). The entire
Unity 6 release series (formerly Unity 2023 Tech Stream) introduced significant
changes that the model does NOT know about. Always cross-reference this directory
before suggesting Unity API calls.
## Post-Cutoff Version Timeline
| Version | Release | Risk Level | Key Theme |
|---------|---------|------------|-----------|
| 6.0 | Oct 2024 | HIGH | Unity 6 rebrand, new rendering features, Entities 1.3, DOTS improvements |
| 6.1 | Nov 2024 | MEDIUM | Bug fixes, stability improvements |
| 6.2 | Dec 2024 | MEDIUM | Performance optimizations, new input system improvements |
| 6.3 LTS | Dec 2025 | HIGH | First LTS since 6.0, production-ready DOTS, enhanced graphics features |
## Major Changes from 2022 LTS to Unity 6.3 LTS
### Breaking Changes
- **Entities/DOTS**: Major API overhaul in Entities 1.0+, complete redesign of ECS patterns
- **Input System**: Legacy Input Manager deprecated, new Input System is default
- **Rendering**: URP/HDRP significant upgrades, SRP Batcher improvements
- **Addressables**: Asset management workflow changes
- **Scripting**: C# 9 support, new API patterns
### New Features (Post-Cutoff)
- **DOTS**: Production-ready Entity Component System (Entities 1.3+)
- **Graphics**: Enhanced URP/HDRP pipelines, GPU Resident Drawer
- **Multiplayer**: Netcode for GameObjects improvements
- **UI Toolkit**: Production-ready for runtime UI (replaces UGUI for new projects)
- **Async Asset Loading**: Improved Addressables performance
- **Web**: WebGPU support
### Deprecated Systems
- **Legacy Input Manager**: Use new Input System package
- **Legacy Particle System**: Use Visual Effect Graph
- **UGUI**: Still supported, but UI Toolkit recommended for new projects
- **Old ECS (GameObjectEntity)**: Replaced by modern DOTS/Entities
## Verified Sources
- Official docs: https://docs.unity3d.com/6000.0/Documentation/Manual/index.html
- Unity 6 release: https://unity.com/releases/unity-6
- Unity 6.3 LTS announcement: https://unity.com/blog/unity-6-3-lts-is-now-available
- Migration guide: https://docs.unity3d.com/6000.0/Documentation/Manual/upgrade-guides.html
- Unity 6 support: https://unity.com/releases/unity-6/support
- C# API reference: https://docs.unity3d.com/6000.0/Documentation/ScriptReference/index.html

View File

@@ -0,0 +1,154 @@
# Unity 6.3 LTS — Breaking Changes
**Last verified:** 2026-02-13
This document tracks breaking API changes and behavioral differences between Unity 2022 LTS
(likely in model training) and Unity 6.3 LTS (current version). Organized by risk level.
## HIGH RISK — Will Break Existing Code
### Entities/DOTS API Complete Overhaul
**Versions:** Entities 1.0+ (Unity 6.0+)
```csharp
// ❌ OLD (pre-Unity 6, GameObjectEntity pattern)
public class HealthComponent : ComponentData {
public float Value;
}
// ✅ NEW (Unity 6+, IComponentData)
public struct HealthComponent : IComponentData {
public float Value;
}
// ❌ OLD: ComponentSystem
public class DamageSystem : ComponentSystem { }
// ✅ NEW: ISystem (unmanaged, Burst-compatible)
public partial struct DamageSystem : ISystem {
public void OnCreate(ref SystemState state) { }
public void OnUpdate(ref SystemState state) { }
}
```
**Migration:** Follow Unity's ECS migration guide. Major architectural changes required.
---
### Input System — Legacy Input Deprecated
**Versions:** Unity 6.0+
```csharp
// ❌ OLD: Input class (deprecated)
if (Input.GetKeyDown(KeyCode.Space)) { }
// ✅ NEW: Input System package
using UnityEngine.InputSystem;
if (Keyboard.current.spaceKey.wasPressedThisFrame) { }
```
**Migration:** Install Input System package, replace all `Input.*` calls with new API.
---
### URP/HDRP Renderer Feature API Changes
**Versions:** Unity 6.0+
```csharp
// ❌ OLD: ScriptableRenderPass.Execute signature
public override void Execute(ScriptableRenderContext context, ref RenderingData data)
// ✅ NEW: Uses RenderGraph API
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
```
**Migration:** Update custom render passes to use RenderGraph API.
---
## MEDIUM RISK — Behavioral Changes
### Addressables — Asset Loading Returns
**Versions:** Unity 6.2+
Asset loading failures now throw exceptions by default instead of returning null.
Add proper exception handling or use `TryLoad` variants.
```csharp
// ❌ OLD: Silent null on failure
var handle = Addressables.LoadAssetAsync<Sprite>("key");
var sprite = handle.Result; // null if failed
// ✅ NEW: Throws on failure, use try/catch or TryLoad
try {
var handle = Addressables.LoadAssetAsync<Sprite>("key");
var sprite = await handle.Task;
} catch (Exception e) {
Debug.LogError($"Failed to load: {e}");
}
```
---
### Physics — Default Solver Iterations Changed
**Versions:** Unity 6.0+
Default solver iterations increased for better stability.
Check `Physics.defaultSolverIterations` if you rely on old behavior.
---
## LOW RISK — Deprecations (Still Functional)
### UGUI (Legacy UI)
**Status:** Deprecated but supported
**Replacement:** UI Toolkit
UGUI still works but UI Toolkit is recommended for new projects.
---
### Legacy Particle System
**Status:** Deprecated
**Replacement:** Visual Effect Graph (VFX Graph)
---
### Old Animation System
**Status:** Deprecated
**Replacement:** Animator Controller (Mecanim)
---
## Platform-Specific Breaking Changes
### WebGL
- **Unity 6.0+**: WebGPU is now the default (WebGL 2.0 fallback available)
- Update shaders for WebGPU compatibility
### Android
- **Unity 6.0+**: Minimum API level raised to 24 (Android 7.0)
### iOS
- **Unity 6.0+**: Minimum deployment target raised to iOS 13
---
## Migration Checklist
When upgrading from 2022 LTS to Unity 6.3 LTS:
- [ ] Audit all DOTS/ECS code (complete rewrite likely needed)
- [ ] Replace `Input` class with Input System package
- [ ] Update custom render passes to RenderGraph API
- [ ] Add exception handling to Addressables calls
- [ ] Test physics behavior (solver iterations changed)
- [ ] Consider migrating UGUI to UI Toolkit for new UI
- [ ] Update WebGL shaders for WebGPU
- [ ] Verify minimum platform versions (Android/iOS)
---
**Sources:**
- https://docs.unity3d.com/6000.0/Documentation/Manual/upgrade-guides.html
- https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/upgrade-guide.html

View File

@@ -0,0 +1,334 @@
# Unity 6.3 LTS — Current Best Practices
**Last verified:** 2026-02-13
Modern Unity 6 patterns that may not be in the LLM's training data.
These are production-ready recommendations as of Unity 6.3 LTS.
---
## Project Setup
### Use Unity 6.3 LTS for Production
- **Tech Stream** (6.4+): Latest features, less stable
- **LTS** (6.3): Production-ready, 2-year support (until Dec 2027)
### Choose the Right Render Pipeline
- **URP (Universal)**: Mobile, cross-platform, good performance ✅ Recommended for most games
- **HDRP (High Definition)**: High-end PC/console, photorealistic
- **Built-in**: Deprecated, avoid for new projects
---
## Scripting
### Use C# 9+ Features (Unity 6 Supports C# 9)
```csharp
// ✅ Record types for data
public record PlayerData(string Name, int Level, float Health);
// ✅ Init-only properties
public class Config {
public string GameMode { get; init; }
}
// ✅ Pattern matching
var result = enemy switch {
Boss boss => boss.Enrage(),
Minion minion => minion.Flee(),
_ => null
};
```
### Async/Await for Asset Loading
```csharp
// ✅ Modern async pattern
public async Task<GameObject> LoadEnemyAsync(string key) {
var handle = Addressables.LoadAssetAsync<GameObject>(key);
return await handle.Task;
}
```
### Use Source Generators for Serialization (Unity 6+)
```csharp
// ✅ Source-generated serialization (faster, less reflection)
[GenerateSerializer]
public partial struct PlayerStats : IComponentData {
public int Health;
public int Mana;
}
```
---
## DOTS/ECS (Production-Ready in Unity 6.3 LTS)
### Use ISystem (Not ComponentSystem)
```csharp
// ✅ Modern unmanaged ISystem (Burst-compatible)
public partial struct MovementSystem : ISystem {
public void OnCreate(ref SystemState state) { }
public void OnUpdate(ref SystemState state) {
foreach (var (transform, speed) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<MoveSpeed>>()) {
transform.ValueRW.Position += speed.ValueRO.Value * SystemAPI.Time.DeltaTime;
}
}
}
```
### Use IJobEntity for Parallel Jobs
```csharp
// ✅ IJobEntity (replaces IJobForEach)
[BurstCompile]
public partial struct DamageJob : IJobEntity {
public float DeltaTime;
void Execute(ref Health health, in DamageOverTime dot) {
health.Value -= dot.DamagePerSecond * DeltaTime;
}
}
// Schedule it
var job = new DamageJob { DeltaTime = SystemAPI.Time.DeltaTime };
job.ScheduleParallel();
```
---
## Input
### Use Input System Package (Not Legacy Input)
```csharp
// ✅ Input Actions (rebindable, cross-platform)
using UnityEngine.InputSystem;
public class PlayerInput : MonoBehaviour {
private PlayerControls controls;
void Awake() {
controls = new PlayerControls();
controls.Gameplay.Jump.performed += ctx => Jump();
}
void OnEnable() => controls.Enable();
void OnDisable() => controls.Disable();
}
```
Create Input Actions asset in editor, generate C# class via inspector.
---
## UI
### Use UI Toolkit for Runtime UI (Production-Ready in Unity 6)
```csharp
// ✅ UI Toolkit (replaces UGUI for new projects)
using UnityEngine.UIElements;
public class MainMenu : MonoBehaviour {
void OnEnable() {
var root = GetComponent<UIDocument>().rootVisualElement;
var playButton = root.Q<Button>("play-button");
playButton.clicked += StartGame;
var scoreLabel = root.Q<Label>("score");
scoreLabel.text = $"High Score: {PlayerPrefs.GetInt("HighScore")}";
}
}
```
**UXML** (UI structure) + **USS** (styling) = HTML/CSS-like workflow.
---
## Asset Management
### Use Addressables (Not Resources)
```csharp
// ✅ Addressables (async, memory-efficient)
using UnityEngine.AddressableAssets;
public async Task SpawnEnemyAsync(string enemyKey) {
var handle = Addressables.InstantiateAsync(enemyKey);
var enemy = await handle.Task;
// Cleanup: release when destroyed
Addressables.ReleaseInstance(enemy);
}
```
**Benefits:** Async loading, remote content delivery, better memory control.
---
## Rendering
### Use RenderGraph API for Custom Passes (URP/HDRP)
```csharp
// ✅ RenderGraph API (Unity 6+)
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("My Pass", out var passData)) {
// Setup pass
builder.SetRenderFunc((PassData data, RasterGraphContext context) => {
// Execute commands
});
}
}
```
**Replaces:** Old `CommandBuffer.Execute()` pattern.
---
## Performance
### Use Burst Compiler + Jobs System
```csharp
// ✅ Burst-compiled job (massive performance gain)
[BurstCompile]
struct ParticleUpdateJob : IJobParallelFor {
public NativeArray<float3> Positions;
public NativeArray<float3> Velocities;
public float DeltaTime;
public void Execute(int index) {
Positions[index] += Velocities[index] * DeltaTime;
}
}
// Schedule
var job = new ParticleUpdateJob {
Positions = positions,
Velocities = velocities,
DeltaTime = Time.deltaTime
};
job.Schedule(positions.Length, 64).Complete();
```
**20-100x faster** than equivalent C# code.
---
### Use GPU Instancing for Repeated Objects
```csharp
// ✅ GPU Instancing (thousands of objects, minimal draw calls)
Graphics.RenderMeshInstanced(
new RenderParams(material),
mesh,
0,
matrices // NativeArray<Matrix4x4>
);
```
---
## Memory Management
### Use NativeContainers (Not Managed Arrays in Jobs)
```csharp
// ✅ NativeArray (no GC, Burst-compatible)
NativeArray<int> data = new NativeArray<int>(1000, Allocator.TempJob);
// ... use in job
data.Dispose(); // Manual cleanup required
// ✅ Or use using statement
using var data = new NativeArray<int>(1000, Allocator.TempJob);
// Auto-disposed
```
---
## Multiplayer
### Use Netcode for GameObjects (Official)
```csharp
// ✅ Unity's official netcode
using Unity.Netcode;
public class Player : NetworkBehaviour {
private NetworkVariable<int> health = new NetworkVariable<int>(100);
[ServerRpc]
public void TakeDamageServerRpc(int damage) {
health.Value -= damage;
}
}
```
**Replaces:** UNet (deprecated), MLAPI (renamed to Netcode for GameObjects).
---
## Testing
### Use Unity Test Framework (NUnit-based)
```csharp
// ✅ Play Mode Test
[UnityTest]
public IEnumerator Player_TakesDamage_HealthDecreases() {
var player = new GameObject().AddComponent<Player>();
player.Health = 100;
player.TakeDamage(25);
yield return null; // Wait one frame
Assert.AreEqual(75, player.Health);
}
```
---
## Debugging
### Use Logging Best Practices
```csharp
// ✅ Structured logging (Unity 6+)
using UnityEngine;
Debug.Log($"Player {playerName} scored {score} points");
// ✅ Conditional compilation for debug code
#if UNITY_EDITOR || DEVELOPMENT_BUILD
Debug.DrawRay(transform.position, direction, Color.red);
#endif
```
---
## Summary: Unity 6 Tech Stack
| Feature | Use This (2026) | Avoid This (Legacy) |
|---------|------------------|----------------------|
| **Input** | Input System package | `Input` class |
| **UI** | UI Toolkit | UGUI (Canvas) |
| **ECS** | ISystem + IJobEntity | ComponentSystem |
| **Rendering** | URP + RenderGraph | Built-in pipeline |
| **Assets** | Addressables | Resources |
| **Jobs** | Burst + IJobParallelFor | Coroutines for heavy work |
| **Multiplayer** | Netcode for GameObjects | UNet |
---
**Sources:**
- https://docs.unity3d.com/6000.0/Documentation/Manual/BestPracticeGuides.html
- https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/index.html

View File

@@ -0,0 +1,156 @@
# Unity 6.3 LTS — Deprecated APIs
**Last verified:** 2026-02-13
Quick lookup table for deprecated APIs and their replacements.
Format: **Don't use X****Use Y instead**
---
## Input
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `Input.GetKey()` | `Keyboard.current[Key.X].isPressed` | New Input System |
| `Input.GetKeyDown()` | `Keyboard.current[Key.X].wasPressedThisFrame` | New Input System |
| `Input.GetMouseButton()` | `Mouse.current.leftButton.isPressed` | New Input System |
| `Input.GetAxis()` | `InputAction` callbacks | New Input System |
| `Input.mousePosition` | `Mouse.current.position.ReadValue()` | New Input System |
**Migration:** Install `com.unity.inputsystem` package.
---
## UI
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `Canvas` (UGUI) | `UIDocument` (UI Toolkit) | UI Toolkit is now production-ready |
| `Text` component | `TextMeshPro` or UI Toolkit `Label` | Better rendering, fewer draw calls |
| `Image` component | UI Toolkit `VisualElement` with background | More flexible styling |
**Migration:** UGUI still works, but UI Toolkit is recommended for new projects.
---
## DOTS/Entities
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `ComponentSystem` | `ISystem` (unmanaged) | Entities 1.0+ complete rewrite |
| `JobComponentSystem` | `ISystem` with `IJobEntity` | Burst-compatible |
| `GameObjectEntity` | Pure ECS workflow | No GameObject conversion |
| `EntityManager.CreateEntity()` (old signature) | `EntityManager.CreateEntity(EntityArchetype)` | Explicit archetype |
| `ComponentDataFromEntity<T>` | `ComponentLookup<T>` | Entities 1.0+ rename |
**Migration:** See Entities package migration guide. Major refactor required.
---
## Rendering
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `CommandBuffer.DrawMesh()` | RenderGraph API | URP/HDRP render passes |
| `OnPreRender()` / `OnPostRender()` | `RenderPipelineManager` callbacks | SRP compatibility |
| `Camera.SetReplacementShader()` | Custom render pass | Not supported in SRP |
---
## Physics
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `Physics.RaycastAll()` | `Physics.RaycastNonAlloc()` | Avoid GC allocations |
| `Rigidbody.velocity` (direct write) | `Rigidbody.AddForce()` | Better physics stability |
---
## Asset Loading
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `Resources.Load()` | Addressables | Better memory control, async loading |
| Synchronous asset loading | `Addressables.LoadAssetAsync()` | Non-blocking |
---
## Animation
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Legacy Animation component | Animator Controller | Mecanim system |
| `Animation.Play()` | `Animator.Play()` | State machine control |
---
## Particles
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Legacy Particle System | Visual Effect Graph | GPU-accelerated, more performant |
---
## Scripting
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `WWW` class | `UnityWebRequest` | Modern async networking |
| `Application.LoadLevel()` | `SceneManager.LoadScene()` | Scene management |
---
## Platform-Specific
### WebGL
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| WebGL 1.0 | WebGL 2.0 or WebGPU | Unity 6+ defaults to WebGPU |
---
## Quick Migration Patterns
### Input Example
```csharp
// ❌ Deprecated
if (Input.GetKeyDown(KeyCode.Space)) {
Jump();
}
// ✅ New Input System
using UnityEngine.InputSystem;
if (Keyboard.current.spaceKey.wasPressedThisFrame) {
Jump();
}
```
### Asset Loading Example
```csharp
// ❌ Deprecated
var prefab = Resources.Load<GameObject>("Enemies/Goblin");
// ✅ Addressables
var handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
await handle.Task;
var prefab = handle.Result;
```
### UI Example
```csharp
// ❌ Deprecated (UGUI)
GetComponent<Text>().text = "Score: 100";
// ✅ TextMeshPro
GetComponent<TextMeshProUGUI>().text = "Score: 100";
// ✅ UI Toolkit
rootVisualElement.Q<Label>("score-label").text = "Score: 100";
```
---
**Sources:**
- https://docs.unity3d.com/6000.0/Documentation/Manual/deprecated-features.html
- https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/Migration.html

View File

@@ -0,0 +1,289 @@
# Unity 6.3 — Animation Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 animation improvements, Timeline enhancements
---
## Overview
Unity 6.3 animation systems:
- **Animator Controller (Mecanim)**: State machine-based (RECOMMENDED)
- **Timeline**: Cinematic sequences, cutscenes
- **Animation Rigging**: Procedural runtime animation
- **Legacy Animation**: Deprecated, avoid
---
## Key Changes from 2022 LTS
### Animation Rigging Package (Production-Ready in Unity 6)
```csharp
// Install: Package Manager > Animation Rigging
// Runtime IK, aim constraints, procedural animation
```
### Timeline Improvements
- Better performance
- More track types
- Improved signal system
---
## Animator Controller (Mecanim)
### Basic Setup
```csharp
// Create: Assets > Create > Animator Controller
// Add to GameObject: Add Component > Animator
// Assign Controller: Animator > Controller = YourAnimatorController
```
### State Transitions
```csharp
Animator animator = GetComponent<Animator>();
// ✅ Trigger transition
animator.SetTrigger("Jump");
// ✅ Bool parameter
animator.SetBool("IsRunning", true);
// ✅ Float parameter (blend trees)
animator.SetFloat("Speed", currentSpeed);
// ✅ Integer parameter
animator.SetInteger("WeaponType", 2);
```
### Animation Layers
- **Base Layer**: Default animations (locomotion)
- **Override Layers**: Replace base layer (e.g., weapon swap)
- **Additive Layers**: Add on top of base (e.g., breathing, aim offset)
```csharp
// Set layer weight (0-1)
animator.SetLayerWeight(1, 0.5f); // 50% blend
```
---
## Blend Trees
### 1D Blend Tree (Speed blending)
```csharp
// Idle (Speed = 0) → Walk (Speed = 0.5) → Run (Speed = 1.0)
animator.SetFloat("Speed", moveSpeed);
```
### 2D Blend Tree (Directional movement)
```csharp
// X-axis: Strafe (-1 to 1)
// Y-axis: Forward/Back (-1 to 1)
animator.SetFloat("MoveX", input.x);
animator.SetFloat("MoveY", input.y);
```
---
## Animation Events
### Trigger Events from Animation Clips
```csharp
// Add in Animation window: Right-click timeline > Add Animation Event
// Must have matching method on GameObject:
public void OnFootstep() {
// Play footstep sound
AudioSource.PlayClipAtPoint(footstepClip, transform.position);
}
public void OnAttackHit() {
// Deal damage
DealDamageInFrontOfPlayer();
}
```
---
## Root Motion
### Character Movement via Animation
```csharp
Animator animator = GetComponent<Animator>();
animator.applyRootMotion = true; // Move character based on animation
void OnAnimatorMove() {
// Custom root motion handling
transform.position += animator.deltaPosition;
transform.rotation *= animator.deltaRotation;
}
```
---
## Animation Rigging (Unity 6+)
### IK (Inverse Kinematics)
```csharp
// Install: Package Manager > Animation Rigging
// Add: Rig Builder component + Rig GameObject
// Two Bone IK (Arm/Leg)
// - Add Two Bone IK Constraint
// - Assign Tip (hand/foot), Mid (elbow/knee), Root (shoulder/hip)
// - Set Target (where hand/foot should reach)
// Runtime control:
TwoBoneIKConstraint ikConstraint = rig.GetComponentInChildren<TwoBoneIKConstraint>();
ikConstraint.data.target = targetTransform;
ikConstraint.weight = 1f; // 0-1 blend
```
### Aim Constraint (Look At)
```csharp
// Character looks at target
MultiAimConstraint aimConstraint = rig.GetComponentInChildren<MultiAimConstraint>();
aimConstraint.data.sourceObjects[0] = new WeightedTransform(targetTransform, 1f);
```
---
## Timeline (Cutscenes)
### Basic Timeline Setup
```csharp
// Create: Assets > Create > Timeline
// Add to GameObject: Add Component > Playable Director
// Assign Timeline: Playable Director > Playable = YourTimeline
// Play from script:
PlayableDirector director = GetComponent<PlayableDirector>();
director.Play();
```
### Timeline Tracks
- **Activation Track**: Enable/disable GameObjects
- **Animation Track**: Play animations on Animator
- **Audio Track**: Synchronized audio playback
- **Cinemachine Track**: Camera movement
- **Signal Track**: Trigger events at specific times
### Signal System (Events)
```csharp
// Create Signal Asset: Assets > Create > Signals > Signal
// Add Signal Emitter to Timeline track
// Add Signal Receiver component to GameObject
public class CutsceneEvents : MonoBehaviour {
public void OnDialogueStart() {
// Triggered by signal
}
}
```
---
## Animation Playback Control
### Play Animation Directly (No State Machine)
```csharp
// ✅ CrossFade (smooth transition)
animator.CrossFade("Attack", 0.2f); // 0.2s transition
// ✅ Play (instant)
animator.Play("Idle");
// ❌ Avoid: Legacy Animation component
Animation anim = GetComponent<Animation>(); // DEPRECATED
```
---
## Animation Curves
### Custom Property Animation
```csharp
// In Animation window: Add Property > Custom Component > Your Script > Your Float
public class WeaponTrail : MonoBehaviour {
public float trailIntensity; // Animated by clip
void Update() {
// Intensity controlled by animation curve
trailRenderer.startWidth = trailIntensity;
}
}
```
---
## Performance Optimization
### Culling
- `Animator > Culling Mode`:
- **Always Animate**: Always update (expensive)
- **Cull Update Transforms**: Stop updating bones when off-screen (RECOMMENDED)
- **Cull Completely**: Stop all animation when off-screen
### LOD (Level of Detail)
- Simpler animations for distant characters
- Reduce skeleton bone count for LOD meshes
---
## Common Patterns
### Check if Animation Finished
```csharp
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName("Attack") && stateInfo.normalizedTime >= 1.0f) {
// Attack animation finished
}
```
### Override Animation Speed
```csharp
animator.speed = 1.5f; // 150% speed
```
### Get Current Animation Name
```csharp
AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(0);
string currentClip = clipInfo[0].clip.name;
```
---
## Debugging
### Animator Window
- `Window > Animation > Animator`
- Visualize state machine, see active state
### Animation Window
- `Window > Animation > Animation`
- Edit animation clips, add events
---
## Sources
- https://docs.unity3d.com/6000.0/Documentation/Manual/AnimationOverview.html
- https://docs.unity3d.com/Packages/com.unity.animation.rigging@1.3/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.timeline@1.8/manual/index.html

View File

@@ -0,0 +1,284 @@
# Unity 6.3 — Audio Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 audio mixer improvements
---
## Overview
Unity 6.3 audio systems:
- **AudioSource**: Play sounds on GameObjects
- **Audio Mixer**: Mix, effect processing, dynamic mixing
- **Spatial Audio**: 3D positioned sound
---
## Basic Audio Playback
### AudioSource Component
```csharp
AudioSource audioSource = GetComponent<AudioSource>();
// ✅ Play
audioSource.Play();
// ✅ Play with delay
audioSource.PlayDelayed(0.5f); // 0.5 seconds
// ✅ Play one-shot (doesn't interrupt current sound)
audioSource.PlayOneShot(clip);
// ✅ Stop
audioSource.Stop();
// ✅ Pause/Resume
audioSource.Pause();
audioSource.UnPause();
```
### Play Sound at Position (Static Method)
```csharp
// ✅ Quick 3D sound playback (auto-destroys when done)
AudioSource.PlayClipAtPoint(clip, transform.position);
// ✅ With volume
AudioSource.PlayClipAtPoint(clip, transform.position, 0.7f);
```
---
## 3D Spatial Audio
### AudioSource 3D Settings
```csharp
AudioSource source = GetComponent<AudioSource>();
// Spatial Blend: 0 = 2D, 1 = 3D
source.spatialBlend = 1.0f; // Fully 3D
// Doppler effect (pitch shift based on velocity)
source.dopplerLevel = 1.0f;
// Distance attenuation
source.minDistance = 1f; // Full volume within this distance
source.maxDistance = 50f; // Inaudible beyond this distance
source.rolloffMode = AudioRolloffMode.Logarithmic; // Natural falloff
```
### Volume Rolloff Curves
- **Logarithmic**: Natural, realistic (RECOMMENDED)
- **Linear**: Steady decrease
- **Custom**: Define your own curve
---
## Audio Mixer (Advanced Mixing)
### Setup Audio Mixer
1. `Assets > Create > Audio Mixer`
2. Open mixer: `Window > Audio > Audio Mixer`
3. Create groups: Master > SFX, Music, Dialogue
### Assign AudioSource to Mixer Group
```csharp
using UnityEngine.Audio;
public AudioMixerGroup sfxGroup;
void Start() {
AudioSource source = GetComponent<AudioSource>();
source.outputAudioMixerGroup = sfxGroup; // Route to SFX group
}
```
### Control Mixer from Code
```csharp
using UnityEngine.Audio;
public AudioMixer audioMixer;
// ✅ Set volume (exposed parameter)
audioMixer.SetFloat("MusicVolume", -10f); // dB (-80 to 0)
// ✅ Get volume
audioMixer.GetFloat("MusicVolume", out float volume);
// Convert linear (0-1) to dB
float volumeDB = Mathf.Log10(volumeLinear) * 20f;
audioMixer.SetFloat("MusicVolume", volumeDB);
```
### Expose Mixer Parameters
In Audio Mixer window:
1. Right-click parameter (e.g., Volume)
2. "Expose 'Volume' to script"
3. Rename in "Exposed Parameters" tab (e.g., "MusicVolume")
---
## Audio Effects
### Add Effects to Mixer Groups
In Audio Mixer:
- Click group (e.g., SFX)
- Click "Add Effect"
- Choose: Reverb, Echo, Low Pass, High Pass, Distortion, etc.
### Duck Music During Dialogue (Sidechain)
```csharp
// Setup in Audio Mixer:
// 1. Create "Duck Volume" snapshot
// 2. Lower music volume in that snapshot
// 3. Transition to snapshot when dialogue plays
public AudioMixerSnapshot normalSnapshot;
public AudioMixerSnapshot duckedSnapshot;
public void PlayDialogue(AudioClip clip) {
duckedSnapshot.TransitionTo(0.5f); // 0.5s transition
audioSource.PlayOneShot(clip);
Invoke(nameof(RestoreMusic), clip.length);
}
void RestoreMusic() {
normalSnapshot.TransitionTo(1.0f); // 1s transition back
}
```
---
## Audio Performance
### Optimize Audio Loading
```csharp
// Audio Import Settings (Inspector):
// - Load Type:
// - Decompress On Load: Small clips (SFX), loads fully into memory
// - Compressed In Memory: Medium clips, decompressed at runtime (RECOMMENDED)
// - Streaming: Large clips (music), streamed from disk
// Compression Format:
// - PCM: Uncompressed, highest quality, largest size
// - ADPCM: 3.5x compression, good for SFX (RECOMMENDED for SFX)
// - Vorbis/MP3: High compression, good for music (RECOMMENDED for music)
```
### Preload Audio
```csharp
// Preload audio clip before playing (avoid stutter)
audioSource.clip.LoadAudioData();
// Check if loaded
if (audioSource.clip.loadState == AudioDataLoadState.Loaded) {
audioSource.Play();
}
```
---
## Music Systems
### Crossfade Between Tracks
```csharp
public IEnumerator CrossfadeMusic(AudioSource from, AudioSource to, float duration) {
float elapsed = 0f;
to.Play();
while (elapsed < duration) {
elapsed += Time.deltaTime;
float t = elapsed / duration;
from.volume = Mathf.Lerp(1f, 0f, t);
to.volume = Mathf.Lerp(0f, 1f, t);
yield return null;
}
from.Stop();
}
```
### Seamless Music Looping
```csharp
// Audio Import Settings:
// - Check "Loop" for seamless music loops
audioSource.loop = true;
```
---
## Common Patterns
### Random Pitch Variation (Avoid Repetition)
```csharp
void PlaySoundWithVariation(AudioClip clip) {
AudioSource source = GetComponent<AudioSource>();
source.pitch = Random.Range(0.9f, 1.1f); // ±10% pitch variation
source.PlayOneShot(clip);
}
```
### Footstep Sounds (Random from Array)
```csharp
public AudioClip[] footstepClips;
void PlayFootstep() {
AudioClip clip = footstepClips[Random.Range(0, footstepClips.Length)];
AudioSource.PlayClipAtPoint(clip, transform.position, 0.5f);
}
```
### Check if Sound is Playing
```csharp
if (audioSource.isPlaying) {
// Sound is currently playing
}
```
---
## Audio Listener
### Single Listener Rule
- Only ONE `AudioListener` should be active at a time
- Usually attached to Main Camera
```csharp
// Disable extra listeners
AudioListener listener = GetComponent<AudioListener>();
listener.enabled = false;
```
---
## Debugging
### Audio Window
- `Window > Audio > Audio Mixer`
- Visualize levels, test snapshots
### Audio Settings
- `Edit > Project Settings > Audio`
- Global volume, DSP buffer size, speaker mode
---
## Sources
- https://docs.unity3d.com/6000.0/Documentation/Manual/Audio.html
- https://docs.unity3d.com/6000.0/Documentation/Manual/AudioMixer.html

View File

@@ -0,0 +1,356 @@
# Unity 6.3 — Input Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 uses new Input System (legacy Input deprecated)
---
## Overview
Unity 6 input systems:
- **Input System Package** (RECOMMENDED): Cross-platform, rebindable, modern
- **Legacy Input Manager**: Deprecated, avoid for new projects
---
## Key Changes from 2022 LTS
### Legacy Input Deprecated in Unity 6
```csharp
// ❌ DEPRECATED: Input class
if (Input.GetKeyDown(KeyCode.Space)) { }
// ✅ NEW: Input System package
using UnityEngine.InputSystem;
if (Keyboard.current.spaceKey.wasPressedThisFrame) { }
```
**Migration Required:** Install `com.unity.inputsystem` package.
---
## Input System Package Setup
### Installation
1. `Window > Package Manager`
2. Search "Input System"
3. Install package
4. Restart Unity when prompted
### Enable New Input System
`Edit > Project Settings > Player > Active Input Handling`:
- **Input System Package (New)** ✅ Recommended
- **Both** (for migration period)
---
## Input Actions (Recommended Pattern)
### Create Input Actions Asset
1. `Assets > Create > Input Actions`
2. Name it (e.g., "PlayerControls")
3. Open asset, define actions:
```
Action Maps:
Gameplay
Actions:
- Move (Value, Vector2)
- Jump (Button)
- Fire (Button)
- Look (Value, Vector2)
```
4. **Generate C# Class**: Check "Generate C# Class" in Inspector
5. Click "Apply"
### Use Generated Input Class
```csharp
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour {
private PlayerControls controls;
void Awake() {
controls = new PlayerControls();
// Subscribe to actions
controls.Gameplay.Jump.performed += ctx => Jump();
controls.Gameplay.Fire.performed += ctx => Fire();
}
void OnEnable() => controls.Enable();
void OnDisable() => controls.Disable();
void Update() {
// Read continuous input
Vector2 move = controls.Gameplay.Move.ReadValue<Vector2>();
transform.Translate(new Vector3(move.x, 0, move.y) * Time.deltaTime);
Vector2 look = controls.Gameplay.Look.ReadValue<Vector2>();
// Apply camera rotation
}
void Jump() {
Debug.Log("Jump!");
}
void Fire() {
Debug.Log("Fire!");
}
}
```
---
## Direct Device Access (Quick & Dirty)
### Keyboard
```csharp
using UnityEngine.InputSystem;
void Update() {
// Current state
if (Keyboard.current.spaceKey.isPressed) { }
// Just pressed this frame
if (Keyboard.current.spaceKey.wasPressedThisFrame) { }
// Just released this frame
if (Keyboard.current.spaceKey.wasReleasedThisFrame) { }
}
```
### Mouse
```csharp
using UnityEngine.InputSystem;
void Update() {
// Mouse position
Vector2 mousePos = Mouse.current.position.ReadValue();
// Mouse delta (movement)
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
// Mouse buttons
if (Mouse.current.leftButton.wasPressedThisFrame) { }
if (Mouse.current.rightButton.isPressed) { }
// Scroll wheel
Vector2 scroll = Mouse.current.scroll.ReadValue();
}
```
### Gamepad
```csharp
using UnityEngine.InputSystem;
void Update() {
Gamepad gamepad = Gamepad.current;
if (gamepad == null) return; // No gamepad connected
// Buttons
if (gamepad.buttonSouth.wasPressedThisFrame) { } // A/Cross
if (gamepad.buttonWest.wasPressedThisFrame) { } // X/Square
// Sticks
Vector2 leftStick = gamepad.leftStick.ReadValue();
Vector2 rightStick = gamepad.rightStick.ReadValue();
// Triggers
float leftTrigger = gamepad.leftTrigger.ReadValue();
float rightTrigger = gamepad.rightTrigger.ReadValue();
// D-Pad
Vector2 dpad = gamepad.dpad.ReadValue();
}
```
### Touch (Mobile)
```csharp
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
void OnEnable() {
EnhancedTouchSupport.Enable();
}
void Update() {
foreach (var touch in UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches) {
Debug.Log($"Touch at {touch.screenPosition}");
}
}
```
---
## Input Action Callbacks
### Action Callbacks (Event-Driven)
```csharp
// started: Input began (e.g., trigger pressed slightly)
controls.Gameplay.Fire.started += ctx => Debug.Log("Fire started");
// performed: Input action triggered (e.g., button fully pressed)
controls.Gameplay.Fire.performed += ctx => Debug.Log("Fire performed");
// canceled: Input released or interrupted
controls.Gameplay.Fire.canceled += ctx => Debug.Log("Fire canceled");
```
### Context Data
```csharp
controls.Gameplay.Move.performed += ctx => {
Vector2 value = ctx.ReadValue<Vector2>();
float duration = ctx.duration; // How long input held
InputControl control = ctx.control; // Which device/control triggered it
};
```
---
## Control Schemes & Device Switching
### Define Control Schemes in Input Actions Asset
```
Control Schemes:
- Keyboard&Mouse (Keyboard, Mouse)
- Gamepad (Gamepad)
- Touch (Touchscreen)
```
### Auto-Switch on Device Change
```csharp
controls.Gameplay.Move.performed += ctx => {
if (ctx.control.device is Keyboard) {
Debug.Log("Using keyboard");
} else if (ctx.control.device is Gamepad) {
Debug.Log("Using gamepad");
}
};
```
---
## Rebinding (Runtime Key Mapping)
### Interactive Rebind
```csharp
using UnityEngine.InputSystem;
public void RebindJumpKey() {
var rebindOperation = controls.Gameplay.Jump.PerformInteractiveRebinding()
.WithControlsExcluding("Mouse") // Exclude mouse bindings
.OnComplete(operation => {
Debug.Log("Rebind complete");
operation.Dispose();
})
.Start();
}
```
### Save/Load Bindings
```csharp
// Save
string rebinds = controls.SaveBindingOverridesAsJson();
PlayerPrefs.SetString("InputBindings", rebinds);
// Load
string rebinds = PlayerPrefs.GetString("InputBindings");
controls.LoadBindingOverridesFromJson(rebinds);
```
---
## Action Types
### Button (Press/Release)
- Single press/release
- Example: Jump, Fire
### Value (Continuous)
- Continuous value (float, Vector2)
- Example: Move, Look, Aim
### Pass-Through (Immediate)
- No processing, immediate value
- Example: Mouse position
---
## Processors (Input Modifiers)
### Scale
```csharp
// In Input Actions asset: Action > Properties > Processors > Add > Scale
// Multiply input by value (e.g., invert Y-axis)
```
### Invert
```csharp
// In Input Actions asset: Action > Properties > Processors > Add > Invert
// Flip input sign
```
### Dead Zone
```csharp
// In Input Actions asset: Action > Properties > Processors > Add > Stick Deadzone
// Ignore small stick movements
```
---
## PlayerInput Component (Simplified Setup)
### Automatic Input Setup
```csharp
// Add Component: Player Input
// Assign Input Actions asset
// Behavior: Send Messages / Invoke Unity Events / Invoke C# Events
// Send Messages example:
public class Player : MonoBehaviour {
public void OnMove(InputValue value) {
Vector2 move = value.Get<Vector2>();
// Handle movement
}
public void OnJump(InputValue value) {
if (value.isPressed) {
Jump();
}
}
}
```
---
## Debugging
### Input Debugger
- `Window > Analysis > Input Debugger`
- See active devices, input values, action states
---
## Sources
- https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/QuickStartGuide.html

View File

@@ -0,0 +1,330 @@
# Unity 6.3 — Navigation Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 NavMesh improvements
---
## Overview
Unity 6 navigation systems:
- **NavMesh**: Built-in pathfinding for AI agents
- **NavMeshComponents**: Package for runtime NavMesh building
---
## NavMesh Basics
### Bake Navigation Mesh
1. Mark walkable surfaces:
- Select GameObject (floor/terrain)
- Inspector > Navigation > Object tab
- Check "Navigation Static"
2. Bake NavMesh:
- `Window > AI > Navigation`
- Bake tab
- Click "Bake"
3. Configure settings:
- **Agent Radius**: How wide the agent is (0.5m default)
- **Agent Height**: How tall the agent is (2m default)
- **Max Slope**: Maximum walkable slope (45° default)
- **Step Height**: Maximum climbable step (0.4m default)
---
## NavMeshAgent (AI Movement)
### Basic Agent Setup
```csharp
using UnityEngine;
using UnityEngine.AI;
public class Enemy : MonoBehaviour {
private NavMeshAgent agent;
public Transform target;
void Start() {
agent = GetComponent<NavMeshAgent>();
}
void Update() {
// ✅ Move to target
agent.SetDestination(target.position);
}
}
```
---
### NavMeshAgent Properties
```csharp
NavMeshAgent agent = GetComponent<NavMeshAgent>();
// Speed
agent.speed = 3.5f;
// Acceleration
agent.acceleration = 8f;
// Stopping distance
agent.stoppingDistance = 2f; // Stop 2m before destination
// Auto-braking (slow down at destination)
agent.autoBraking = true;
// Rotation speed
agent.angularSpeed = 120f; // Degrees per second
// Obstacle avoidance
agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
```
---
### Check Path Status
```csharp
void Update() {
agent.SetDestination(target.position);
// Check if agent has a path
if (agent.hasPath) {
// Check if path is complete
if (agent.pathStatus == NavMeshPathStatus.PathComplete) {
Debug.Log("Valid path");
} else if (agent.pathStatus == NavMeshPathStatus.PathPartial) {
Debug.Log("Partial path (destination unreachable)");
} else {
Debug.Log("Invalid path");
}
}
// Check if agent reached destination
if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) {
Debug.Log("Reached destination");
}
}
```
---
### Calculate Path (Don't Move Yet)
```csharp
NavMeshPath path = new NavMeshPath();
agent.CalculatePath(targetPosition, path);
if (path.status == NavMeshPathStatus.PathComplete) {
// Valid path exists
agent.SetPath(path); // Apply the path
}
```
---
## NavMesh Areas (Walkable Costs)
### Define Areas
`Window > AI > Navigation > Areas tab`
- **Walkable**: Cost 1 (default)
- **Not Walkable**: Unwalkable
- **Jump**: Cost 2 (prefer other routes)
- **Custom**: Define your own
### Assign Area Costs
```csharp
// Prefer shorter paths over low-cost paths
agent.areaMask = NavMesh.AllAreas; // Walk on all areas
// Only walk on "Walkable" area (avoid "Jump")
agent.areaMask = 1 << NavMesh.GetAreaFromName("Walkable");
```
---
## NavMesh Obstacles (Dynamic Obstacles)
### NavMeshObstacle Component
```csharp
// Add: GameObject > Add Component > NavMesh Obstacle
// Carve: Create hole in NavMesh (agents avoid)
// Don't Carve: Agent pushes through (local avoidance)
```
### Dynamic Carving (Moving Obstacles)
```csharp
NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
obstacle.carving = true; // Create dynamic hole in NavMesh
```
---
## Off-Mesh Links (Jumps, Teleports)
### Create Off-Mesh Link
1. `GameObject > Create Empty` (at jump start)
2. Add `Off Mesh Link` component
3. Set Start/End transforms
4. Configure:
- **Bi-Directional**: Can traverse both ways
- **Cost Override**: Path cost for this link
### Detect Off-Mesh Link Traversal
```csharp
void Update() {
// Check if agent is on an off-mesh link
if (agent.isOnOffMeshLink) {
// Manually traverse (e.g., play jump animation)
StartCoroutine(TraverseOffMeshLink());
}
}
IEnumerator TraverseOffMeshLink() {
OffMeshLinkData data = agent.currentOffMeshLinkData;
Vector3 startPos = agent.transform.position;
Vector3 endPos = data.endPos;
float duration = 0.5f;
float elapsed = 0f;
while (elapsed < duration) {
agent.transform.position = Vector3.Lerp(startPos, endPos, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
agent.CompleteOffMeshLink(); // Resume normal pathfinding
}
```
---
## NavMeshComponents Package (Runtime Baking)
### Installation
1. `Window > Package Manager`
2. Add from Git URL: `com.unity.ai.navigation`
### Runtime NavMesh Baking
```csharp
using Unity.AI.Navigation;
public class NavMeshBuilder : MonoBehaviour {
public NavMeshSurface surface;
void Start() {
// Bake NavMesh at runtime
surface.BuildNavMesh();
}
void UpdateNavMesh() {
// Update NavMesh after terrain changes
surface.UpdateNavMesh(surface.navMeshData);
}
}
```
---
## Common Patterns
### Patrol Between Waypoints
```csharp
public Transform[] waypoints;
private int currentWaypoint = 0;
void Update() {
if (!agent.pathPending && agent.remainingDistance < 0.5f) {
// Reached waypoint, move to next
currentWaypoint = (currentWaypoint + 1) % waypoints.Length;
agent.SetDestination(waypoints[currentWaypoint].position);
}
}
```
### Chase Player
```csharp
public Transform player;
public float chaseRange = 10f;
void Update() {
float distance = Vector3.Distance(transform.position, player.position);
if (distance <= chaseRange) {
agent.SetDestination(player.position);
} else {
agent.ResetPath(); // Stop moving
}
}
```
### Flee from Player
```csharp
public Transform player;
public float fleeRange = 5f;
void Update() {
float distance = Vector3.Distance(transform.position, player.position);
if (distance <= fleeRange) {
// Run away from player
Vector3 fleeDirection = transform.position - player.position;
Vector3 fleeTarget = transform.position + fleeDirection.normalized * 10f;
agent.SetDestination(fleeTarget);
}
}
```
---
## Debugging
### NavMesh Visualization
- `Window > AI > Navigation > Bake tab`
- Check "Show NavMesh" to visualize walkable areas
### Agent Path Gizmos
```csharp
void OnDrawGizmos() {
if (agent != null && agent.hasPath) {
Gizmos.color = Color.green;
Vector3[] corners = agent.path.corners;
for (int i = 0; i < corners.Length - 1; i++) {
Gizmos.DrawLine(corners[i], corners[i + 1]);
}
}
}
```
---
## Performance Tips
- **Limit Obstacle Avoidance Quality**: Use `LowQualityObstacleAvoidance` for distant agents
- **Update Frequency**: Don't call `SetDestination()` every frame if target hasn't moved
- **Area Masks**: Limit walkable areas to reduce pathfinding search space
- **NavMesh Tiles**: Use tiled NavMesh for large worlds (NavMeshComponents package)
---
## Sources
- https://docs.unity3d.com/6000.0/Documentation/Manual/Navigation.html
- https://docs.unity3d.com/Packages/com.unity.ai.navigation@2.0/manual/index.html

View File

@@ -0,0 +1,351 @@
# Unity 6.3 — Networking Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 uses Netcode for GameObjects (UNet deprecated)
---
## Overview
Unity 6 networking options:
- **Netcode for GameObjects** (RECOMMENDED): Official Unity multiplayer framework
- **Mirror**: Community-driven (UNet successor)
- **Photon**: Third-party service (PUN2)
- **Custom**: Low-level sockets
**UNet (Legacy)**: Deprecated, do not use.
---
## Netcode for GameObjects
### Installation
1. `Window > Package Manager`
2. Search "Netcode for GameObjects"
3. Install `com.unity.netcode.gameobjects`
---
## Basic Setup
### NetworkManager
```csharp
// Add to scene: GameObject > Add Component > NetworkManager
// Or create custom NetworkManager:
using Unity.Netcode;
public class CustomNetworkManager : MonoBehaviour {
void Start() {
NetworkManager.Singleton.StartHost(); // Server + client
// OR
NetworkManager.Singleton.StartServer(); // Dedicated server
// OR
NetworkManager.Singleton.StartClient(); // Client only
}
}
```
---
## NetworkObject (Networked GameObjects)
### Mark GameObject as Networked
1. Add `NetworkObject` component to GameObject
2. Must be in root of prefab (not nested)
3. Register prefab in `NetworkManager > NetworkPrefabs List`
### Spawn Network Objects
```csharp
using Unity.Netcode;
public class GameManager : NetworkBehaviour {
public GameObject playerPrefab;
[ServerRpc(RequireOwnership = false)]
public void SpawnPlayerServerRpc(ulong clientId) {
GameObject player = Instantiate(playerPrefab);
player.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId);
}
}
```
---
## NetworkBehaviour (Networked Scripts)
### NetworkBehaviour Base Class
```csharp
using Unity.Netcode;
public class Player : NetworkBehaviour {
// Called when spawned on network
public override void OnNetworkSpawn() {
if (IsOwner) {
// Only run on owner's client
GetComponent<Camera>().enabled = true;
}
}
void Update() {
if (!IsOwner) return; // Only owner can control
// Handle input
if (Input.GetKey(KeyCode.W)) {
MoveServerRpc(Vector3.forward);
}
}
[ServerRpc]
void MoveServerRpc(Vector3 direction) {
// Runs on server
transform.position += direction * Time.deltaTime;
}
}
```
---
## Network Variables (Synchronized State)
### NetworkVariable<T>
```csharp
using Unity.Netcode;
public class Player : NetworkBehaviour {
// ✅ Auto-synced across clients
private NetworkVariable<int> health = new NetworkVariable<int>(100);
public override void OnNetworkSpawn() {
// Subscribe to value changes
health.OnValueChanged += OnHealthChanged;
}
void OnHealthChanged(int oldValue, int newValue) {
Debug.Log($"Health changed: {oldValue} -> {newValue}");
UpdateHealthUI(newValue);
}
[ServerRpc]
public void TakeDamageServerRpc(int damage) {
// Only server can modify NetworkVariable
health.Value -= damage;
}
}
```
### NetworkVariable Permissions
```csharp
// Server can write, clients read-only (default)
private NetworkVariable<int> score = new NetworkVariable<int>();
// Owner can write
private NetworkVariable<int> ammo = new NetworkVariable<int>(
default,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Owner
);
```
---
## RPCs (Remote Procedure Calls)
### ServerRpc (Client → Server)
```csharp
// Client calls, server executes
[ServerRpc]
void FireWeaponServerRpc() {
// Runs on server
Debug.Log("Server: Weapon fired");
}
// Call from client:
if (IsOwner && Input.GetKeyDown(KeyCode.Space)) {
FireWeaponServerRpc();
}
```
### ClientRpc (Server → All Clients)
```csharp
// Server calls, all clients execute
[ClientRpc]
void PlayExplosionClientRpc(Vector3 position) {
// Runs on all clients
Instantiate(explosionPrefab, position, Quaternion.identity);
}
// Call from server:
[ServerRpc]
void ExplodeServerRpc(Vector3 position) {
// Server logic
DealDamageToNearbyPlayers(position);
// Notify all clients
PlayExplosionClientRpc(position);
}
```
### RPC Parameters
```csharp
// ✅ Supported: Primitives, structs, strings, arrays
[ServerRpc]
void SetNameServerRpc(string playerName) { }
[ClientRpc]
void UpdateScoresClientRpc(int[] scores) { }
// ❌ Not supported: MonoBehaviour, GameObject (use NetworkObjectReference)
```
---
## Network Ownership
### Check Ownership
```csharp
if (IsOwner) {
// This client owns this NetworkObject
}
if (IsServer) {
// Running on server
}
if (IsClient) {
// Running on client
}
if (IsLocalPlayer) {
// This is the local player object
}
```
### Transfer Ownership
```csharp
// Server transfers ownership
NetworkObject netObj = GetComponent<NetworkObject>();
netObj.ChangeOwnership(newOwnerClientId);
```
---
## NetworkObjectReference (Pass GameObjects in RPCs)
```csharp
using Unity.Netcode;
[ServerRpc]
void AttackTargetServerRpc(NetworkObjectReference targetRef) {
if (targetRef.TryGet(out NetworkObject target)) {
// Got the target object
target.GetComponent<Health>().TakeDamage(10);
}
}
// Call:
NetworkObject targetNetObj = target.GetComponent<NetworkObject>();
AttackTargetServerRpc(targetNetObj);
```
---
## Client-Server Architecture
### Server-Authoritative Pattern (RECOMMENDED)
```csharp
public class Player : NetworkBehaviour {
private NetworkVariable<Vector3> position = new NetworkVariable<Vector3>();
void Update() {
if (IsOwner) {
// Client: Send input to server
Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
MoveServerRpc(input);
}
// All clients: Sync to networked position
transform.position = position.Value;
}
[ServerRpc]
void MoveServerRpc(Vector3 input) {
// Server: Validate and apply movement
position.Value += input * Time.deltaTime * moveSpeed;
}
}
```
---
## Network Transport
### Unity Transport (Default)
```csharp
// Configured in NetworkManager:
// - Transport: Unity Transport
// - Address: 127.0.0.1 (localhost) or server IP
// - Port: 7777 (default)
```
### Connection Events
```csharp
void Start() {
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected;
}
void OnClientConnected(ulong clientId) {
Debug.Log($"Client {clientId} connected");
}
void OnClientDisconnected(ulong clientId) {
Debug.Log($"Client {clientId} disconnected");
}
```
---
## Performance Tips
### Reduce Network Traffic
- Use `NetworkVariable` for state that changes infrequently
- Batch multiple changes before syncing
- Use delta compression for large data
### Prediction & Reconciliation
- Run movement locally for responsiveness
- Reconcile with server authoritative state
- Use interpolation for smooth movement
---
## Debugging
### Network Profiler
- `Window > Analysis > Network Profiler`
- Monitor bandwidth, RPC calls, variable updates
### Network Simulator (Test Latency/Packet Loss)
- `NetworkManager > Network Simulator`
- Add artificial lag and packet loss for testing
---
## Sources
- https://docs-multiplayer.unity3d.com/netcode/current/about/
- https://docs-multiplayer.unity3d.com/netcode/current/learn/bossroom/

View File

@@ -0,0 +1,268 @@
# Unity 6.3 — Physics Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 physics improvements, solver changes
---
## Overview
Unity 6.3 uses **PhysX 5.1** (improved from PhysX 4.x in 2022 LTS):
- Better solver stability
- Improved performance
- Enhanced collision detection
---
## Key Changes from 2022 LTS
### Default Solver Iterations Increased
Unity 6 increased default solver iterations for better stability:
```csharp
// Default changed from 6 to 8 iterations
Physics.defaultSolverIterations = 8; // Check if relying on old behavior
```
### Enhanced Collision Detection
```csharp
// ✅ Unity 6: Improved Continuous Collision Detection (CCD)
rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
// Better handling of fast-moving objects
```
---
## Core Physics Components
### Rigidbody
```csharp
// ✅ Best practice: Use AddForce, not direct velocity writes
Rigidbody rb = GetComponent<Rigidbody>();
rb.AddForce(Vector3.forward * 10f, ForceMode.Impulse);
// ❌ Avoid: Direct velocity assignment (can cause instability)
rb.velocity = new Vector3(0, 10, 0); // Only use when necessary
```
### Colliders
```csharp
// Primitive colliders: Box, Sphere, Capsule (cheapest)
// Mesh colliders: Expensive, use only for static geometry
// ✅ Compound colliders (multiple primitives) > single mesh collider
```
---
## Raycasting
### Efficient Raycasting (Avoid Allocations)
```csharp
// ✅ Non-allocating raycast
if (Physics.Raycast(origin, direction, out RaycastHit hit, maxDistance)) {
Debug.Log($"Hit: {hit.collider.name}");
}
// ✅ Multiple hits (non-allocating)
RaycastHit[] results = new RaycastHit[10];
int hitCount = Physics.RaycastNonAlloc(origin, direction, results, maxDistance);
for (int i = 0; i < hitCount; i++) {
Debug.Log($"Hit {i}: {results[i].collider.name}");
}
// ❌ Avoid: RaycastAll (allocates array every call)
RaycastHit[] hits = Physics.RaycastAll(origin, direction); // GC allocation!
```
### LayerMask for Selective Raycasting
```csharp
// ✅ Use LayerMask to filter collisions
int layerMask = 1 << LayerMask.NameToLayer("Enemy");
Physics.Raycast(origin, direction, out RaycastHit hit, maxDistance, layerMask);
```
---
## Physics Queries
### OverlapSphere (Check for nearby objects)
```csharp
// ✅ Non-allocating version
Collider[] results = new Collider[10];
int count = Physics.OverlapSphereNonAlloc(center, radius, results);
for (int i = 0; i < count; i++) {
// Process results[i]
}
```
### SphereCast (Thick raycast)
```csharp
// Useful for character controllers
if (Physics.SphereCast(origin, radius, direction, out RaycastHit hit, maxDistance)) {
// Hit something with a sphere-shaped ray
}
```
---
## Collision Events
### OnCollisionEnter / Stay / Exit
```csharp
void OnCollisionEnter(Collision collision) {
// Triggered when collision starts
Debug.Log($"Collided with {collision.gameObject.name}");
// Access contact points
foreach (ContactPoint contact in collision.contacts) {
Debug.DrawRay(contact.point, contact.normal, Color.red, 2f);
}
}
```
### OnTriggerEnter / Stay / Exit
```csharp
void OnTriggerEnter(Collider other) {
// Trigger collider (Is Trigger = true)
if (other.CompareTag("Pickup")) {
Destroy(other.gameObject);
}
}
```
---
## Character Controllers
### CharacterController Component
```csharp
CharacterController controller = GetComponent<CharacterController>();
// ✅ Move with collision detection
Vector3 move = transform.forward * speed * Time.deltaTime;
controller.Move(move);
// Apply gravity manually
if (!controller.isGrounded) {
velocity.y += Physics.gravity.y * Time.deltaTime;
}
controller.Move(velocity * Time.deltaTime);
```
---
## Physics Materials
### Friction & Bounciness
```csharp
// Create: Assets > Create > Physic Material
// Assign to collider: Collider > Material
// PhysicMaterial settings:
// - Dynamic Friction: 0.6 (sliding friction)
// - Static Friction: 0.6 (starting friction)
// - Bounciness: 0.0 - 1.0
// - Friction Combine: Average, Minimum, Maximum, Multiply
// - Bounce Combine: Average, Minimum, Maximum, Multiply
```
---
## Joints
### Fixed Joint (Attach two rigidbodies)
```csharp
FixedJoint joint = gameObject.AddComponent<FixedJoint>();
joint.connectedBody = otherRigidbody;
```
### Hinge Joint (Door, wheel)
```csharp
HingeJoint hinge = gameObject.AddComponent<HingeJoint>();
hinge.axis = Vector3.up; // Rotation axis
hinge.useLimits = true;
hinge.limits = new JointLimits { min = -90, max = 90 };
```
---
## Performance Optimization
### Physics Layer Collision Matrix
`Edit > Project Settings > Physics > Layer Collision Matrix`
- Disable unnecessary collision checks between layers
- Massive performance gain
### Fixed Timestep
`Edit > Project Settings > Time > Fixed Timestep`
- Default: 0.02 (50 FPS physics)
- Lower = more accurate, higher CPU cost
- Match game's target framerate if possible
### Simplified Collision Geometry
- Use primitive colliders (box, sphere, capsule) over mesh colliders
- Bake mesh colliders at build time, not runtime
---
## Common Patterns
### Ground Check (Character Controller)
```csharp
bool IsGrounded() {
float rayLength = 0.1f;
return Physics.Raycast(transform.position, Vector3.down, rayLength);
}
```
### Apply Explosion Force
```csharp
void ApplyExplosion(Vector3 explosionPos, float radius, float force) {
Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
foreach (Collider hit in colliders) {
Rigidbody rb = hit.GetComponent<Rigidbody>();
if (rb != null) {
rb.AddExplosionForce(force, explosionPos, radius);
}
}
}
```
---
## Debugging
### Physics Debugger (Unity 6+)
- `Window > Analysis > Physics Debugger`
- Visualize colliders, contacts, queries
### Gizmos
```csharp
void OnDrawGizmos() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, detectionRadius);
}
```
---
## Sources
- https://docs.unity3d.com/6000.0/Documentation/Manual/PhysicsOverview.html
- https://docs.unity3d.com/ScriptReference/Physics.html

View File

@@ -0,0 +1,238 @@
# Unity 6.3 — Rendering Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** LLM trained on Unity 2022 LTS; Unity 6 has major rendering changes
---
## Overview
Unity 6.3 LTS uses **Scriptable Render Pipelines (SRP)** as the modern rendering architecture:
- **URP (Universal Render Pipeline)**: Cross-platform, mobile-friendly (RECOMMENDED)
- **HDRP (High Definition Render Pipeline)**: High-end PC/console, photorealistic
- **Built-in Pipeline**: Deprecated, avoid for new projects
---
## Key Changes from 2022 LTS
### RenderGraph API (Unity 6+)
Custom render passes now use RenderGraph instead of CommandBuffer:
```csharp
// ✅ Unity 6+ (RenderGraph)
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) {
using var builder = renderGraph.AddRasterRenderPass<PassData>("MyPass", out var passData);
builder.SetRenderFunc((PassData data, RasterGraphContext ctx) => {
// Rendering commands
});
}
// ❌ Old (CommandBuffer - still works but deprecated)
public override void Execute(ScriptableRenderContext context, ref RenderingData data) { }
```
### GPU Resident Drawer (Unity 6+)
Automatic batching for massive draw call reduction:
```csharp
// Enable in URP Asset settings:
// Rendering > GPU Resident Drawer = Enabled
// Automatically batches thousands of objects with minimal CPU overhead
```
---
## URP Quick Reference
### Creating a URP Asset
1. `Assets > Create > Rendering > URP Asset (with Universal Renderer)`
2. Assign to `Project Settings > Graphics > Scriptable Render Pipeline Settings`
### URP Renderer Features
Add custom render passes:
```csharp
using UnityEngine.Rendering.Universal;
public class OutlineRendererFeature : ScriptableRendererFeature {
OutlineRenderPass pass;
public override void Create() {
pass = new OutlineRenderPass();
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData data) {
renderer.EnqueuePass(pass);
}
}
```
---
## Materials & Shaders
### Shader Graph (Visual Shader Editor)
Unity 6 Shader Graph is production-ready for all shader types:
```csharp
// Create: Assets > Create > Shader Graph > URP > Lit Shader Graph
// No code needed, visual node-based editing
```
### HLSL Custom Shaders (URP)
```hlsl
// URP Lit shader template
Shader "Custom/URPLit" {
Properties {
_BaseColor ("Base Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
Pass {
Name "ForwardLit"
Tags { "LightMode"="UniversalForward" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes {
float4 positionOS : POSITION;
};
struct Varyings {
float4 positionCS : SV_POSITION;
};
Varyings vert(Attributes input) {
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
return output;
}
half4 frag(Varyings input) : SV_Target {
return half4(1, 0, 0, 1); // Red
}
ENDHLSL
}
}
}
```
---
## Lighting
### Baked Lighting (Unity 6 Progressive Lightmapper)
```csharp
// Mark objects as static: Inspector > Static > Contribute GI
// Bake: Window > Rendering > Lighting > Generate Lighting
```
### Real-Time Lights (URP)
```csharp
// Main Light (Directional): Auto-handled by URP
// Additional Lights: Limited by "Additional Lights" setting in URP Asset
// Check light count in shader:
int lightCount = GetAdditionalLightsCount();
```
---
## Post-Processing
### Volume System (Unity 6+)
```csharp
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
// Add Volume component to GameObject
// Add Volume Profile asset
// Configure effects: Bloom, Color Grading, Depth of Field, etc.
// Script access:
Volume volume = GetComponent<Volume>();
if (volume.profile.TryGet<Bloom>(out var bloom)) {
bloom.intensity.value = 2.5f;
}
```
---
## Performance
### SRP Batcher (Auto-batching)
```csharp
// Enable: URP Asset > Advanced > SRP Batcher = Enabled
// Batches draws with same shader variant (minimal CPU overhead)
```
### GPU Instancing
```csharp
// Material: Enable "Enable GPU Instancing" checkbox
// Batches identical meshes (same material + mesh)
Graphics.RenderMeshInstanced(
new RenderParams(material),
mesh,
0,
matrices // NativeArray<Matrix4x4>
);
```
### Occlusion Culling
```csharp
// Window > Rendering > Occlusion Culling
// Bake occlusion data for static geometry
```
---
## Common Patterns
### Custom Camera Rendering
```csharp
// Get URP camera data
var cameraData = frameData.Get<UniversalCameraData>();
var camera = cameraData.camera;
// Access render targets
var colorTarget = cameraData.renderer.cameraColorTargetHandle;
```
### Screen-Space Effects
```csharp
// Create ScriptableRendererFeature
// Inject pass at specific point: AfterRenderingOpaques, AfterRenderingTransparents, etc.
```
---
## Debugging
### Frame Debugger
- `Window > Analysis > Frame Debugger`
- Step through draw calls, inspect state
### Rendering Debugger (Unity 6+)
- `Window > Analysis > Rendering Debugger`
- Live view of URP settings, overdraw, lighting
---
## Sources
- https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@17.0/manual/index.html
- https://docs.unity3d.com/6000.0/Documentation/Manual/render-pipelines.html

View File

@@ -0,0 +1,377 @@
# Unity 6.3 — UI Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** Unity 6 UI Toolkit is production-ready for runtime UI
---
## Overview
Unity 6 UI systems:
- **UI Toolkit** (RECOMMENDED): Modern, performant, HTML/CSS-like (production-ready in Unity 6)
- **UGUI (Canvas)**: Legacy system, still supported but not recommended for new projects
- **IMGUI**: Editor-only, deprecated for runtime UI
---
## UI Toolkit (Modern UI)
### Setup UI Document
1. Create UXML (UI structure):
- `Assets > Create > UI Toolkit > UI Document`
2. Create USS (styling):
- `Assets > Create > UI Toolkit > StyleSheet`
3. Add to scene:
- `GameObject > UI Toolkit > UI Document`
- Assign UXML to `UIDocument > Source Asset`
---
### UXML (UI Structure)
```xml
<!-- MainMenu.uxml -->
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:VisualElement class="container">
<ui:Label text="Main Menu" class="title" />
<ui:Button name="play-button" text="Play" />
<ui:Button name="settings-button" text="Settings" />
<ui:Button name="quit-button" text="Quit" />
</ui:VisualElement>
</ui:UXML>
```
---
### USS (Styling)
```css
/* MainMenu.uss */
.container {
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: rgb(30, 30, 30);
}
.title {
font-size: 48px;
color: white;
margin-bottom: 20px;
}
Button {
width: 200px;
height: 50px;
margin: 10px;
font-size: 24px;
}
Button:hover {
background-color: rgb(100, 150, 200);
}
```
---
### C# Scripting (UI Toolkit)
```csharp
using UnityEngine;
using UnityEngine.UIElements;
public class MainMenu : MonoBehaviour {
void OnEnable() {
var root = GetComponent<UIDocument>().rootVisualElement;
// Query elements by name
var playButton = root.Q<Button>("play-button");
var settingsButton = root.Q<Button>("settings-button");
var quitButton = root.Q<Button>("quit-button");
// Register callbacks
playButton.clicked += OnPlayClicked;
settingsButton.clicked += OnSettingsClicked;
quitButton.clicked += Application.Quit;
}
void OnPlayClicked() {
Debug.Log("Play clicked");
// Load game scene
}
void OnSettingsClicked() {
Debug.Log("Settings clicked");
// Open settings menu
}
}
```
---
### Common UI Elements
```csharp
// Label (text display)
var label = root.Q<Label>("score-label");
label.text = "Score: 100";
// Button
var button = root.Q<Button>("submit-button");
button.clicked += OnSubmit;
// TextField (text input)
var textField = root.Q<TextField>("name-input");
string playerName = textField.value;
// Toggle (checkbox)
var toggle = root.Q<Toggle>("music-toggle");
bool isMusicEnabled = toggle.value;
// Slider
var slider = root.Q<Slider>("volume-slider");
float volume = slider.value; // 0-1
// DropdownField (dropdown menu)
var dropdown = root.Q<DropdownField>("difficulty-dropdown");
dropdown.choices = new List<string> { "Easy", "Normal", "Hard" };
dropdown.value = "Normal";
```
---
### Dynamic UI Creation (No UXML)
```csharp
void CreateUI() {
var root = GetComponent<UIDocument>().rootVisualElement;
// Create elements
var container = new VisualElement();
container.AddToClassList("container");
var label = new Label("Hello, UI Toolkit!");
var button = new Button(() => Debug.Log("Clicked")) { text = "Click Me" };
container.Add(label);
container.Add(button);
root.Add(container);
}
```
---
### USS Flexbox Layout
```css
/* Horizontal layout */
.horizontal {
flex-direction: row;
}
/* Vertical layout (default) */
.vertical {
flex-direction: column;
}
/* Center children */
.centered {
align-items: center;
justify-content: center;
}
/* Spacing */
.spaced {
justify-content: space-between;
}
```
---
## UGUI (Legacy Canvas UI)
### Basic Setup (Still Works in Unity 6)
```csharp
// GameObject > UI > Canvas (creates Canvas, EventSystem)
// UI Elements:
// - Text (use TextMeshPro instead)
// - Button
// - Image
// - Slider
// - Toggle
// - InputField
```
---
### UGUI Scripting
```csharp
using UnityEngine;
using UnityEngine.UI;
using TMPro; // TextMeshPro
public class LegacyUI : MonoBehaviour {
public TextMeshProUGUI scoreText;
public Button playButton;
public Slider volumeSlider;
void Start() {
// Update text
scoreText.text = "Score: 100";
// Button click
playButton.onClick.AddListener(OnPlayClicked);
// Slider value changed
volumeSlider.onValueChanged.AddListener(OnVolumeChanged);
}
void OnPlayClicked() {
Debug.Log("Play clicked");
}
void OnVolumeChanged(float value) {
AudioListener.volume = value;
}
}
```
---
### TextMeshPro (Better Text Rendering)
```csharp
// Install: Window > TextMeshPro > Import TMP Essential Resources
// Use TMP_Text instead of Unity's Text component
using TMPro;
public TextMeshProUGUI tmpText;
tmpText.text = "High Quality Text";
tmpText.fontSize = 24;
tmpText.color = Color.white;
```
---
## Canvas Settings (UGUI)
### Render Modes
```csharp
// Screen Space - Overlay: UI rendered on top of everything (no camera needed)
// Screen Space - Camera: UI rendered by specific camera (allows effects)
// World Space: UI in 3D world (e.g., floating health bars)
```
### Canvas Scaler (Responsive UI)
```csharp
// UI Scale Mode:
// - Constant Pixel Size: UI elements have fixed pixel size
// - Scale With Screen Size: UI scales based on reference resolution (RECOMMENDED)
// - Constant Physical Size: UI elements have fixed physical size (cm)
// Example: Scale With Screen Size
// Reference Resolution: 1920x1080
// Screen Match Mode: Match Width Or Height (0.5 = balanced)
```
---
## Layout Groups (UGUI)
### Horizontal Layout Group
```csharp
// Auto-arranges children horizontally
// Add: GameObject > Add Component > Horizontal Layout Group
```
### Vertical Layout Group
```csharp
// Auto-arranges children vertically
```
### Grid Layout Group
```csharp
// Arranges children in a grid
```
---
## Performance (UI Toolkit vs UGUI)
### UI Toolkit Advantages
- ✅ Faster rendering (retained mode)
- ✅ Better for complex UIs with many elements
- ✅ Easier styling (CSS-like)
- ✅ Better for dynamic UIs
### UGUI Advantages
- ✅ More mature, widely documented
- ✅ Better integration with Unity Editor
- ✅ Easier for beginners
---
## Common Patterns
### Health Bar (UI Toolkit)
```csharp
var healthBar = root.Q<VisualElement>("health-bar");
healthBar.style.width = new StyleLength(new Length(healthPercent, LengthUnit.Percent));
```
### Health Bar (UGUI)
```csharp
public Image healthBarImage;
void UpdateHealth(float percent) {
healthBarImage.fillAmount = percent; // 0-1
}
```
---
### Fade In/Out (UI Toolkit)
```csharp
IEnumerator FadeIn(VisualElement element, float duration) {
float elapsed = 0f;
while (elapsed < duration) {
elapsed += Time.deltaTime;
element.style.opacity = Mathf.Lerp(0f, 1f, elapsed / duration);
yield return null;
}
}
```
---
## Debugging
### UI Toolkit Debugger
- `Window > UI Toolkit > Debugger`
- Inspect element hierarchy, styles, layout
### UGUI Event System Debugger
- Select EventSystem in Hierarchy
- Inspector shows active input module, raycast info
---
## Sources
- https://docs.unity3d.com/6000.0/Documentation/Manual/UIElements.html
- https://docs.unity3d.com/Packages/com.unity.ui@2.0/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/index.html

View File

@@ -0,0 +1,378 @@
# Unity 6.3 — Addressables
**Last verified:** 2026-02-13
**Status:** Production-Ready
**Package:** `com.unity.addressables` (Package Manager)
---
## Overview
**Addressables** is Unity's advanced asset management system that replaces `Resources.Load()`
with async loading, remote content delivery, and better memory control.
**Use Addressables for:**
- Async asset loading (non-blocking)
- DLC and remote content
- Memory optimization (load/unload on demand)
- Asset dependency management
- Large projects with many assets
**DON'T use Addressables for:**
- Tiny projects (overhead not worth it)
- Assets needed immediately at startup (use direct references)
---
## Installation
### Install via Package Manager
1. `Window > Package Manager`
2. Unity Registry > Search "Addressables"
3. Install `Addressables`
---
## Core Concepts
### 1. **Addressable Assets**
- Assets marked as "Addressable" (assigned unique keys)
- Can be loaded by key at runtime
### 2. **Asset Groups**
- Organize assets (e.g., "UI", "Weapons", "Level1")
- Groups determine build settings (local vs remote)
### 3. **Async Loading**
- All loading is async (non-blocking)
- Returns `AsyncOperationHandle`
### 4. **Reference Counting**
- Addressables tracks asset usage
- Must manually release assets when done
---
## Setup
### 1. Mark Assets as Addressable
1. Select asset in Project window
2. Inspector > Check "Addressable"
3. Assign key (e.g., "Enemies/Goblin")
**OR via script:**
```csharp
#if UNITY_EDITOR
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
AddressableAssetSettings.AddAssetEntry(guid, "MyAssetKey", "Default Local Group");
#endif
```
---
### 2. Create Groups
`Window > Asset Management > Addressables > Groups`
- **Default Local Group**: Bundled with build
- **Remote Group**: Hosted on server (CDN)
---
## Basic Loading
### Load Asset Async
```csharp
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AssetLoader : MonoBehaviour {
async void Start() {
// ✅ Load asset asynchronously
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded) {
GameObject prefab = handle.Result;
Instantiate(prefab);
} else {
Debug.LogError("Failed to load asset");
}
// ⚠️ IMPORTANT: Release when done
Addressables.Release(handle);
}
}
```
---
### Load and Instantiate
```csharp
async void SpawnEnemy() {
// ✅ Load and instantiate in one step
AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync("Enemies/Goblin");
await handle.Task;
GameObject enemy = handle.Result;
// Use enemy...
// ✅ Release when destroying
Addressables.ReleaseInstance(enemy);
}
```
---
### Load Multiple Assets
```csharp
async void LoadAllWeapons() {
// Load all assets with label "Weapons"
AsyncOperationHandle<IList<GameObject>> handle = Addressables.LoadAssetsAsync<GameObject>("Weapons", null);
await handle.Task;
foreach (var weapon in handle.Result) {
Debug.Log($"Loaded: {weapon.name}");
}
Addressables.Release(handle);
}
```
---
## Asset Labels (Tags)
### Assign Labels
1. `Window > Asset Management > Addressables > Groups`
2. Select asset > Inspector > Labels > Add label (e.g., "Level1", "UI")
### Load by Label
```csharp
// Load all assets with label "Level1"
Addressables.LoadAssetsAsync<GameObject>("Level1", null);
```
---
## Remote Content (DLC)
### Setup Remote Groups
1. Create new group: `Window > Addressables > Groups > Create New Group > Packed Assets`
2. Group Settings:
- **Build Path**: `ServerData/[BuildTarget]`
- **Load Path**: `http://yourcdn.com/content/[BuildTarget]`
### Build Remote Content
1. `Window > Asset Management > Addressables > Build > New Build > Default Build Script`
2. Upload `ServerData/` folder to CDN
3. Game loads assets from remote server
---
## Preloading / Caching
### Download Dependencies
```csharp
async void PreloadLevel() {
// Download all assets in group without loading into memory
AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync("Level1");
await handle.Task;
// Now "Level1" assets are cached, load instantly
Addressables.Release(handle);
}
```
### Check Download Size
```csharp
async void CheckDownloadSize() {
AsyncOperationHandle<long> handle = Addressables.GetDownloadSizeAsync("Level1");
await handle.Task;
long sizeInBytes = handle.Result;
Debug.Log($"Download size: {sizeInBytes / (1024 * 1024)} MB");
Addressables.Release(handle);
}
```
---
## Memory Management
### Release Assets
```csharp
// ✅ Always release when done
Addressables.Release(handle);
// ✅ For instantiated objects
Addressables.ReleaseInstance(gameObject);
```
### Check Reference Count
```csharp
// Addressables uses reference counting
// Asset is unloaded when refCount == 0
```
---
## Asset References (Inspector-Assigned)
### Use AssetReference
```csharp
using UnityEngine.AddressableAssets;
public class EnemySpawner : MonoBehaviour {
// ✅ Assign in Inspector (drag & drop)
public AssetReference enemyPrefab;
async void SpawnEnemy() {
AsyncOperationHandle<GameObject> handle = enemyPrefab.InstantiateAsync();
await handle.Task;
GameObject enemy = handle.Result;
// Use enemy...
enemyPrefab.ReleaseInstance(enemy);
}
}
```
---
## Scenes
### Load Addressable Scene
```csharp
using UnityEngine.SceneManagement;
async void LoadScene() {
AsyncOperationHandle<SceneInstance> handle = Addressables.LoadSceneAsync("MainMenu", LoadSceneMode.Additive);
await handle.Task;
SceneInstance sceneInstance = handle.Result;
// Scene loaded
// Unload scene
await Addressables.UnloadSceneAsync(handle).Task;
}
```
---
## Common Patterns
### Lazy Loading (Load on Demand)
```csharp
Dictionary<string, AsyncOperationHandle<GameObject>> loadedAssets = new();
async Task<GameObject> GetAsset(string key) {
if (!loadedAssets.ContainsKey(key)) {
var handle = Addressables.LoadAssetAsync<GameObject>(key);
await handle.Task;
loadedAssets[key] = handle;
}
return loadedAssets[key].Result;
}
```
---
### Cleanup on Scene Unload
```csharp
void OnDestroy() {
// Release all handles
foreach (var handle in loadedAssets.Values) {
Addressables.Release(handle);
}
loadedAssets.Clear();
}
```
---
## Content Catalog Updates (Live Updates)
### Check for Catalog Updates
```csharp
async void CheckForUpdates() {
AsyncOperationHandle<List<string>> handle = Addressables.CheckForCatalogUpdates();
await handle.Task;
if (handle.Result.Count > 0) {
Debug.Log("Updates available");
await Addressables.UpdateCatalogs(handle.Result).Task;
}
Addressables.Release(handle);
}
```
---
## Performance Tips
- **Preload** frequently used assets at startup
- **Release** assets immediately when not needed
- Use **labels** to batch-load related assets
- **Cache** remote content for offline use
---
## Debugging
### Addressables Event Viewer
`Window > Asset Management > Addressables > Event Viewer`
- Shows all load/release operations
- Memory usage per asset
- Reference counts
### Addressables Profiler
`Window > Asset Management > Addressables > Profiler`
- Real-time asset usage
- Bundle loading stats
---
## Migration from Resources
```csharp
// ❌ OLD: Resources.Load (synchronous, blocks frame)
GameObject prefab = Resources.Load<GameObject>("Enemies/Goblin");
// ✅ NEW: Addressables (async, non-blocking)
var handle = await Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin").Task;
GameObject prefab = handle.Result;
```
---
## Sources
- https://docs.unity3d.com/Packages/com.unity.addressables@2.0/manual/index.html
- https://learn.unity.com/tutorial/addressables

View File

@@ -0,0 +1,348 @@
# Unity 6.3 — Cinemachine
**Last verified:** 2026-02-13
**Status:** Production-Ready
**Package:** `com.unity.cinemachine` v3.0+ (Package Manager)
---
## Overview
**Cinemachine** is Unity's virtual camera system that enables professional, dynamic camera
behavior without manual scripting. It's the industry standard for Unity camera work.
**Use Cinemachine for:**
- 3rd person follow cameras
- Cutscenes and cinematics
- Camera blending and transitions
- Dynamic camera framing
- Screen shake and camera effects
**⚠️ Knowledge Gap:** Cinemachine 3.0 (Unity 6) is a major rewrite from 2.x.
Many API names and components changed.
---
## Installation
### Install via Package Manager
1. `Window > Package Manager`
2. Unity Registry > Search "Cinemachine"
3. Install `Cinemachine` (version 3.0+)
---
## Core Concepts
### 1. **Virtual Cameras**
- Define camera behavior (position, rotation, lens)
- Multiple virtual cameras can exist; only one is "live" at a time
### 2. **Cinemachine Brain**
- Component on main Camera
- Blends between virtual cameras
- Applies virtual camera settings to Unity Camera
### 3. **Priorit**ies**
- Virtual cameras have priority values
- Highest priority camera is active
- Blends smoothly when priority changes
---
## Basic Setup
### 1. Add Cinemachine Brain to Main Camera
```csharp
// Automatically added when creating first virtual camera
// Or manually: Add Component > Cinemachine Brain
```
### 2. Create Virtual Camera
`GameObject > Cinemachine > Cinemachine Camera`
This creates a **CinemachineCamera** GameObject with default settings.
---
## Virtual Camera Components
### CinemachineCamera (Unity 6 / Cinemachine 3.0+)
```csharp
using Unity.Cinemachine;
public class CameraController : MonoBehaviour {
public CinemachineCamera virtualCamera;
void Start() {
// Set priority (higher = active)
virtualCamera.Priority = 10;
// Set follow target
virtualCamera.Follow = playerTransform;
// Set look-at target
virtualCamera.LookAt = playerTransform;
}
}
```
---
## Follow Modes (Body Component)
### 3rd Person Follow (Orbital Follow)
```csharp
// In Inspector:
// CinemachineCamera > Body > 3rd Person Follow
// Configure:
// - Shoulder Offset: (0.5, 0, 0) for over-shoulder
// - Camera Distance: 5.0
// - Vertical Damping: 0.5 (smooth up/down)
```
### Framing Transposer (Smooth Follow)
```csharp
// CinemachineCamera > Body > Position Composer
// Configure:
// - Screen Position: Center (0.5, 0.5)
// - Dead Zone: Don't move camera if target within zone
// - Damping: Smooth following
```
### Hard Lock (Exact Follow)
```csharp
// CinemachineCamera > Body > Hard Lock to Target
// Camera exactly matches target position (no offset or damping)
```
---
## Aim Modes (Aim Component)
### Composer (Frame Target)
```csharp
// CinemachineCamera > Aim > Composer
// Configure:
// - Tracked Object Offset: Aim at target's head instead of feet
// - Screen Position: Where target appears on screen
// - Dead Zone: Don't rotate if target within zone
```
### Look At Target
```csharp
// CinemachineCamera > Aim > Rotate With Follow Target
// Camera rotation matches target rotation (e.g., first-person)
```
---
## Blending Between Cameras
### Priority-Based Blending
```csharp
public CinemachineCamera normalCamera; // Priority: 10
public CinemachineCamera aimCamera; // Priority: 5
void StartAiming() {
// Set aim camera to higher priority
aimCamera.Priority = 15; // Now active
// Brain automatically blends from normalCamera to aimCamera
}
void StopAiming() {
aimCamera.Priority = 5; // Back to normal
}
```
### Custom Blend Times
```csharp
// Create Custom Blends Asset:
// Assets > Create > Cinemachine > Cinemachine Blender Settings
// In Cinemachine Brain:
// - Custom Blends = your asset
// - Configure blend times per camera pair
```
---
## Camera Shake
### Impulse Source (Trigger Shake)
```csharp
using Unity.Cinemachine;
public class ExplosionShake : MonoBehaviour {
public CinemachineImpulseSource impulseSource;
void Explode() {
// Trigger camera shake
impulseSource.GenerateImpulse();
}
}
```
### Impulse Listener (Receive Shake)
```csharp
// Add to CinemachineCamera:
// Add Component > CinemachineImpulseListener
// Impulse listener automatically receives shake from nearby Impulse Sources
```
---
## Freelook Camera (Third Person with Mouse Look)
### Cinemachine Free Look
```csharp
// GameObject > Cinemachine > Cinemachine Free Look
// Creates 3 rigs (Top, Middle, Bottom) that blend based on vertical input
// Configure:
// - Orbit Radius: Distance from target
// - Height Offset: Camera height at each rig
// - X/Y Axis: Mouse or joystick input
```
---
## State-Driven Camera (Anim ator-Based)
### Cinemachine State-Driven Camera
```csharp
// GameObject > Cinemachine > Cinemachine State-Driven Camera
// Configure:
// - Animated Target: Character with Animator
// - Layer: Animator layer to track
// - State: Assign camera per animation state (Idle, Run, Jump, etc.)
// Camera automatically switches based on animation state
```
---
## Dolly Tracks (Cutscenes)
### Cinemachine Dolly Track
```csharp
// 1. Create Spline: GameObject > Cinemachine > Cinemachine Spline
// 2. Create Dolly Camera:
// GameObject > Cinemachine > Cinemachine Camera
// Body > Spline Dolly
// Assign Spline
// 3. Animate dolly position on spline (Timeline or script)
```
---
## Common Patterns
### Third-Person Follow Camera
```csharp
// CinemachineCamera
// - Follow: Player Transform
// - Body: 3rd Person Follow (shoulder offset, distance: 5)
// - Aim: Composer (frame player at center)
```
---
### Aiming Camera (Zoom In)
```csharp
// Normal Camera (Priority 10):
// - Distance: 5.0
// Aim Camera (Priority 5):
// - Distance: 2.0
// - FOV: Narrower
// Script:
void StartAiming() {
aimCamera.Priority = 15; // Blend to aim camera
}
```
---
### Cutscene Camera Sequence
```csharp
// Use Timeline:
// 1. Create Timeline (Assets > Create > Timeline)
// 2. Add Cinemachine Track
// 3. Add virtual cameras as clips
// 4. Timeline automatically blends between cameras
```
---
## Migration from Cinemachine 2.x (Unity 2021)
### API Changes (Unity 6 / Cinemachine 3.0)
```csharp
// ❌ OLD (Cinemachine 2.x):
CinemachineVirtualCamera vcam;
vcam.m_Follow = target;
// ✅ NEW (Cinemachine 3.0+):
CinemachineCamera vcam;
vcam.Follow = target; // Cleaner API
```
**Major Changes:**
- `CinemachineVirtualCamera``CinemachineCamera`
- `m_Follow`, `m_LookAt``Follow`, `LookAt` (no "m_" prefix)
- Components renamed for clarity
- Better performance
---
## Performance Tips
- Limit active virtual cameras (only activate when needed)
- Use lower-priority cameras instead of destroying/creating
- Disable virtual cameras when far from player
---
## Debugging
### Cinemachine Debug
```csharp
// Window > Analysis > Cinemachine Debugger
// Shows active camera, blend info, shot quality
```
---
## Sources
- https://docs.unity3d.com/Packages/com.unity.cinemachine@3.0/manual/index.html
- https://learn.unity.com/tutorial/cinemachine

View File

@@ -0,0 +1,420 @@
# Unity 6.3 — DOTS / Entities (ECS)
**Last verified:** 2026-02-13
**Status:** Production-Ready (Entities 1.3+, Unity 6.3 LTS)
**Package:** `com.unity.entities` (Package Manager)
---
## Overview
**DOTS (Data-Oriented Technology Stack)** is Unity's high-performance ECS (Entity Component System)
framework. It's designed for games with massive scale (1000s-10,000s of entities).
**Use DOTS for:**
- RTS games (1000s of units)
- Simulations (crowds, traffic, physics)
- Procedural content generation
- Performance-critical systems
**DON'T use DOTS for:**
- Small games (overhead not worth it)
- Gameplay requiring frequent structural changes
- Heavy use of UnityEngine APIs (MonoBehaviour is easier)
**⚠️ Knowledge Gap:** Entities 1.0+ (Unity 6) is a complete rewrite from 0.x.
Many tutorials for Entities 0.x are now outdated.
---
## Installation
### Install via Package Manager
1. `Window > Package Manager`
2. Unity Registry > Search "Entities"
3. Install:
- `Entities` (ECS core)
- `Burst` (LLVM compiler)
- `Jobs` (auto-installed)
- `Mathematics` (SIMD math)
---
## Core Concepts
### 1. **Entity**
- Lightweight ID (int)
- No behavior, just an identifier
### 2. **Component**
- Data only (no methods)
- Struct implementing `IComponentData`
### 3. **System**
- Logic that operates on components
- Struct implementing `ISystem`
### 4. **Archetype**
- Unique combination of component types
- Entities with same components share archetype
---
## Basic ECS Pattern
### Define Component
```csharp
using Unity.Entities;
using Unity.Mathematics;
// ✅ Component: Data only, no methods
public struct Position : IComponentData {
public float3 Value;
}
public struct Velocity : IComponentData {
public float3 Value;
}
```
---
### Define System
```csharp
using Unity.Entities;
using Unity.Burst;
// ✅ System: Logic that processes entities
[BurstCompile]
public partial struct MovementSystem : ISystem {
[BurstCompile]
public void OnUpdate(ref SystemState state) {
float deltaTime = SystemAPI.Time.DeltaTime;
// Query all entities with Position + Velocity
foreach (var (transform, velocity) in
SystemAPI.Query<RefRW<Position>, RefRO<Velocity>>()) {
transform.ValueRW.Value += velocity.ValueRO.Value * deltaTime;
}
}
}
```
---
### Create Entities
```csharp
using Unity.Entities;
using Unity.Mathematics;
public partial class EntitySpawner : SystemBase {
protected override void OnUpdate() {
var em = EntityManager;
// Create entity
Entity entity = em.CreateEntity();
// Add components
em.AddComponentData(entity, new Position { Value = float3.zero });
em.AddComponentData(entity, new Velocity { Value = new float3(1, 0, 0) });
}
}
```
---
## Hybrid ECS (MonoBehaviour + ECS)
### Baker (Convert GameObject to Entity)
```csharp
using Unity.Entities;
using UnityEngine;
public class PlayerAuthoring : MonoBehaviour {
public float speed;
}
public class PlayerBaker : Baker<PlayerAuthoring> {
public override void Bake(PlayerAuthoring authoring) {
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new Position { Value = authoring.transform.position });
AddComponent(entity, new Velocity { Value = new float3(authoring.speed, 0, 0) });
}
}
```
**How it works:**
1. Add `PlayerAuthoring` to GameObject in editor
2. Baker automatically converts to Entity at runtime
3. Entity has Position + Velocity components
---
## Queries
### Query All Entities with Components
```csharp
foreach (var (position, velocity) in
SystemAPI.Query<RefRW<Position>, RefRO<Velocity>>()) {
position.ValueRW.Value += velocity.ValueRO.Value * deltaTime;
}
```
---
### Query with Entity
```csharp
foreach (var (position, velocity, entity) in
SystemAPI.Query<RefRW<Position>, RefRO<Velocity>>().WithEntityAccess()) {
// Access entity ID
Debug.Log($"Entity: {entity}");
}
```
---
### Query with Filters
```csharp
// Only entities with "Enemy" tag
foreach (var position in
SystemAPI.Query<RefRW<Position>>().WithAll<EnemyTag>()) {
// Process enemies only
}
```
---
## Jobs (Parallel Execution)
### IJobEntity (Parallel Foreach)
```csharp
using Unity.Entities;
using Unity.Burst;
[BurstCompile]
public partial struct MovementJob : IJobEntity {
public float DeltaTime;
// Execute runs in parallel for each entity
void Execute(ref Position position, in Velocity velocity) {
position.Value += velocity.Value * DeltaTime;
}
}
[BurstCompile]
public partial struct MovementSystem : ISystem {
public void OnUpdate(ref SystemState state) {
var job = new MovementJob {
DeltaTime = SystemAPI.Time.DeltaTime
};
job.ScheduleParallel(); // Parallel execution
}
}
```
---
## Burst Compiler (Performance)
### Enable Burst
```csharp
using Unity.Burst;
[BurstCompile] // 10-100x faster than regular C#
public partial struct MySystem : ISystem {
[BurstCompile]
public void OnUpdate(ref SystemState state) {
// Burst-compiled code
}
}
```
**Burst Restrictions:**
- No managed references (classes, strings, etc.)
- Only blittable types (structs, primitives, Unity.Mathematics types)
- No exceptions
---
## Entity Command Buffers (Structural Changes)
### Deferred Structural Changes
```csharp
using Unity.Entities;
public partial struct SpawnSystem : ISystem {
public void OnUpdate(ref SystemState state) {
var ecb = new EntityCommandBuffer(Allocator.Temp);
// Defer entity creation (don't modify during iteration)
foreach (var spawner in SystemAPI.Query<Spawner>()) {
Entity newEntity = ecb.CreateEntity();
ecb.AddComponent(newEntity, new Position { Value = spawner.SpawnPos });
}
ecb.Playback(state.EntityManager); // Apply changes
ecb.Dispose();
}
}
```
---
## Dynamic Buffers (Array-Like Components)
### Define Dynamic Buffer
```csharp
public struct PathWaypoint : IBufferElementData {
public float3 Position;
}
```
### Use Dynamic Buffer
```csharp
// Add buffer to entity
var buffer = EntityManager.AddBuffer<PathWaypoint>(entity);
buffer.Add(new PathWaypoint { Position = new float3(0, 0, 0) });
buffer.Add(new PathWaypoint { Position = new float3(10, 0, 0) });
// Query buffer
foreach (var buffer in SystemAPI.Query<DynamicBuffer<PathWaypoint>>()) {
foreach (var waypoint in buffer) {
Debug.Log(waypoint.Position);
}
}
```
---
## Tags (Zero-Size Components)
### Define Tag
```csharp
public struct EnemyTag : IComponentData { } // Empty component = tag
```
### Use Tag for Filtering
```csharp
// Only process entities with EnemyTag
foreach (var position in
SystemAPI.Query<RefRW<Position>>().WithAll<EnemyTag>()) {
// Enemy-specific logic
}
```
---
## System Ordering
### Explicit Ordering
```csharp
[UpdateBefore(typeof(PhysicsSystem))]
public partial struct InputSystem : ISystem { }
[UpdateAfter(typeof(PhysicsSystem))]
public partial struct RenderSystem : ISystem { }
```
---
## Performance Patterns
### Chunk Iteration (Maximum Performance)
```csharp
public void OnUpdate(ref SystemState state) {
var query = SystemAPI.QueryBuilder().WithAll<Position, Velocity>().Build();
var chunks = query.ToArchetypeChunkArray(Allocator.Temp);
var positionType = state.GetComponentTypeHandle<Position>();
var velocityType = state.GetComponentTypeHandle<Velocity>(true); // Read-only
foreach (var chunk in chunks) {
var positions = chunk.GetNativeArray(ref positionType);
var velocities = chunk.GetNativeArray(ref velocityType);
for (int i = 0; i < chunk.Count; i++) {
positions[i] = new Position {
Value = positions[i].Value + velocities[i].Value * deltaTime
};
}
}
chunks.Dispose();
}
```
---
## Migration from MonoBehaviour
```csharp
// ❌ OLD: MonoBehaviour (OOP)
public class Enemy : MonoBehaviour {
public float speed;
void Update() {
transform.position += Vector3.forward * speed * Time.deltaTime;
}
}
// ✅ NEW: DOTS (ECS)
public struct EnemyData : IComponentData {
public float Speed;
}
[BurstCompile]
public partial struct EnemyMovementSystem : ISystem {
public void OnUpdate(ref SystemState state) {
float dt = SystemAPI.Time.DeltaTime;
foreach (var (transform, enemy) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<EnemyData>>()) {
transform.ValueRW.Position += new float3(0, 0, enemy.ValueRO.Speed * dt);
}
}
}
```
---
## Debugging
### Entities Hierarchy Window
`Window > Entities > Hierarchy`
- Shows all entities and their components
- Filter by archetype, component type
### Entities Profiler
`Window > Analysis > Profiler > Entities`
- System execution times
- Memory usage per archetype
---
## Sources
- https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.burst@1.8/manual/index.html
- https://learn.unity.com/tutorial/entity-component-system

View File

@@ -0,0 +1,210 @@
# Unreal Engine 5.7 — Optional Plugins & Systems
**Last verified:** 2026-02-13
This document indexes **optional plugins and systems** available in Unreal Engine 5.7.
These are NOT part of the core engine but are commonly used for specific game types.
---
## How to Use This Guide
**✅ Detailed Documentation Available** - See `plugins/` directory for comprehensive guides
**🟡 Brief Overview Only** - Links to official docs, use WebSearch for details
**⚠️ Experimental** - May have breaking changes in future versions
**📦 Plugin Required** - Must be enabled in `Edit > Plugins`
---
## Production-Ready Systems (Detailed Docs Available)
### ✅ Gameplay Ability System (GAS)
- **Purpose:** Modular ability system (abilities, attributes, effects, cooldowns, costs)
- **When to use:** RPGs, MOBAs, shooters with abilities, any ability-based gameplay
- **Knowledge Gap:** GAS stable since UE4, UE5 improvements post-cutoff
- **Status:** Production-Ready
- **Plugin:** `GameplayAbilities` (built-in, enable in Plugins)
- **Detailed Docs:** [plugins/gameplay-ability-system.md](plugins/gameplay-ability-system.md)
- **Official:** https://docs.unrealengine.com/5.7/en-US/gameplay-ability-system-for-unreal-engine/
---
### ✅ CommonUI
- **Purpose:** Cross-platform UI framework (automatic gamepad/mouse/touch input routing)
- **When to use:** Multi-platform games (console + PC), input-agnostic UI
- **Knowledge Gap:** Production-ready in UE5+, major improvements post-cutoff
- **Status:** Production-Ready
- **Plugin:** `CommonUI` (built-in, enable in Plugins)
- **Detailed Docs:** [plugins/common-ui.md](plugins/common-ui.md)
- **Official:** https://docs.unrealengine.com/5.7/en-US/commonui-plugin-for-advanced-user-interfaces-in-unreal-engine/
---
### ✅ Gameplay Camera System
- **Purpose:** Modular camera management (camera modes, blending, context-aware cameras)
- **When to use:** Games needing dynamic camera behavior (3rd person, aiming, vehicles)
- **Knowledge Gap:** NEW in UE 5.5, completely post-cutoff
- **Status:** ⚠️ Experimental (UE 5.5-5.7)
- **Plugin:** `GameplayCameras` (built-in, enable in Plugins)
- **Detailed Docs:** [plugins/gameplay-camera-system.md](plugins/gameplay-camera-system.md)
- **Official:** https://docs.unrealengine.com/5.7/en-US/gameplay-cameras-in-unreal-engine/
---
### ✅ PCG (Procedural Content Generation)
- **Purpose:** Node-based procedural world generation (foliage, props, terrain details)
- **When to use:** Open worlds, procedural levels, large-scale environment population
- **Knowledge Gap:** Experimental in UE 5.0-5.6, production-ready in 5.7
- **Status:** Production-Ready (as of UE 5.7)
- **Plugin:** `PCG` (built-in, enable in Plugins)
- **Detailed Docs:** [plugins/pcg.md](plugins/pcg.md)
- **Official:** https://docs.unrealengine.com/5.7/en-US/procedural-content-generation-in-unreal-engine/
---
## Other Production-Ready Plugins (Brief Overview)
### 🟡 Mass Entity
- **Purpose:** High-performance ECS for large-scale AI/crowds (10,000+ entities)
- **When to use:** RTS, city simulators, massive crowds, large-scale AI
- **Status:** Production-Ready (UE 5.1+)
- **Plugin:** `MassEntity`, `MassGameplay`, `MassCrowd`
- **Official:** https://docs.unrealengine.com/5.7/en-US/mass-entity-in-unreal-engine/
---
### 🟡 Niagara Fluids
- **Purpose:** GPU fluid simulation (smoke, fire, liquids)
- **When to use:** Realistic fire/smoke effects, water simulation
- **Status:** Experimental → Production-Ready (UE 5.4+)
- **Plugin:** `NiagaraFluids` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/niagara-fluids-in-unreal-engine/
---
### 🟡 Water Plugin
- **Purpose:** Ocean, river, lake rendering with buoyancy
- **When to use:** Games with water bodies, boats, swimming
- **Status:** Production-Ready (UE 5.0+)
- **Plugin:** `Water` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/water-system-in-unreal-engine/
---
### 🟡 Landmass Plugin
- **Purpose:** Terrain sculpting and landscape editing
- **When to use:** Large-scale terrain modification, procedural landscapes
- **Status:** Production-Ready
- **Plugin:** `Landmass` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/landmass-plugin-in-unreal-engine/
---
### 🟡 Chaos Destruction
- **Purpose:** Real-time fracture and destruction
- **When to use:** Destructible environments (walls, buildings, objects)
- **Status:** Production-Ready (UE 5.0+)
- **Plugin:** `ChaosDestruction` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/destruction-in-unreal-engine/
---
### 🟡 Chaos Vehicle
- **Purpose:** Advanced vehicle physics (wheeled vehicles, suspension)
- **When to use:** Racing games, vehicle-heavy gameplay
- **Status:** Production-Ready (replaces PhysX Vehicles)
- **Plugin:** `ChaosVehicles` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/chaos-vehicles-overview-in-unreal-engine/
---
### 🟡 Geometry Scripting
- **Purpose:** Runtime procedural mesh generation and editing
- **When to use:** Dynamic mesh creation, procedural modeling
- **Status:** Production-Ready (UE 5.1+)
- **Plugin:** `GeometryScripting` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/geometry-scripting-in-unreal-engine/
---
### 🟡 Motion Design Tools
- **Purpose:** Motion graphics, procedural animation, keyframe animation
- **When to use:** UI animations, procedural motion, keyframed sequences
- **Status:** Experimental → Production-Ready (UE 5.4+)
- **Plugin:** `MotionDesign` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/motion-design-mode-in-unreal-engine/
---
## Experimental Plugins (Use with Caution)
### ⚠️ AI Assistant (UE 5.7+)
- **Purpose:** In-editor AI guidance and help
- **Status:** Experimental
- **Plugin:** Enable in UE 5.7 settings
- **Official:** Announced in UE 5.7 release
---
### ⚠️ OpenXR (VR/AR)
- **Purpose:** Cross-platform VR/AR support
- **When to use:** VR/AR games
- **Status:** Production-Ready for VR, Experimental for AR
- **Plugin:** `OpenXR` (built-in)
- **Official:** https://docs.unrealengine.com/5.7/en-US/openxr-in-unreal-engine/
---
### ⚠️ Online Subsystem (EOS, Steam, etc.)
- **Purpose:** Platform-agnostic online services (matchmaking, friends, achievements)
- **When to use:** Multiplayer games with online features
- **Status:** Production-Ready
- **Plugin:** `OnlineSubsystem`, `OnlineSubsystemEOS`, `OnlineSubsystemSteam`
- **Official:** https://docs.unrealengine.com/5.7/en-US/online-subsystem-in-unreal-engine/
---
## Deprecated Plugins (Avoid for New Projects)
### ❌ PhysX Vehicles
- **Deprecated:** Use Chaos Vehicles instead
- **Status:** Legacy, not recommended
---
### ❌ Old Replication Graph
- **Deprecated:** Replaced by Iris (UE 5.1+)
- **Status:** Use Iris for modern networking
---
## On-Demand WebSearch Strategy
For plugins NOT listed above, use the following approach when users ask:
1. **WebSearch** for latest documentation: `"Unreal Engine 5.7 [plugin name]"`
2. Verify if plugin is:
- Post-cutoff (beyond May 2025 training data)
- Experimental vs Production-Ready
- Still supported in UE 5.7
3. Optionally cache findings in `plugins/[plugin-name].md` for future reference
---
## Quick Decision Guide
**I need abilities/skills/buffs****Gameplay Ability System (GAS)**
**I need cross-platform UI (console + PC)****CommonUI**
**I need dynamic cameras****Gameplay Camera System**
**I need procedural worlds****PCG**
**I need large crowds (1000s of AI)****Mass Entity**
**I need destructible environments****Chaos Destruction**
**I need vehicles****Chaos Vehicles**
**I need water/oceans****Water Plugin**
**I need VR/AR****OpenXR**
---
**Last Updated:** 2026-02-13
**Engine Version:** Unreal Engine 5.7
**LLM Knowledge Cutoff:** May 2025

View File

@@ -0,0 +1,54 @@
# Unreal Engine — Version Reference
| Field | Value |
|-------|-------|
| **Engine Version** | Unreal Engine 5.7 |
| **Release Date** | November 2025 |
| **Project Pinned** | 2026-02-13 |
| **Last Docs Verified** | 2026-02-13 |
| **LLM Knowledge Cutoff** | May 2025 |
## Knowledge Gap Warning
The LLM's training data likely covers Unreal Engine up to ~5.3. Versions 5.4, 5.5,
5.6, and 5.7 introduced significant changes that the model does NOT know about.
Always cross-reference this directory before suggesting Unreal API calls.
## Post-Cutoff Version Timeline
| Version | Release | Risk Level | Key Theme |
|---------|---------|------------|-----------|
| 5.4 | ~Mid 2025 | HIGH | Motion Design tools, animation improvements, PCG enhancements |
| 5.5 | ~Sep 2025 | HIGH | Megalights (millions of lights), animation authoring, MegaCity demo |
| 5.6 | ~Oct 2025 | MEDIUM | Performance optimizations, bug fixes |
| 5.7 | Nov 2025 | HIGH | PCG production-ready, Substrate production-ready, AI assistant |
## Major Changes from UE 5.3 to UE 5.7
### Breaking Changes
- **Substrate Material System**: New material framework (replaces legacy materials)
- **PCG (Procedural Content Generation)**: Production-ready, major API changes
- **Megalights**: New lighting system (millions of dynamic lights)
- **Animation Authoring**: New rigging and animation tools
- **AI Assistant**: In-editor AI guidance (experimental)
### New Features (Post-Cutoff)
- **Megalights**: Dynamic lighting at massive scale (millions of lights)
- **Substrate Materials**: Production-ready modular material system
- **PCG Framework**: Procedural world generation (production-ready in 5.7)
- **Enhanced Virtual Production**: MetaHuman integration, deeper VP workflows
- **Animation Improvements**: Better rigging, blending, procedural animation
- **AI Assistant**: In-editor AI help (experimental)
### Deprecated Systems
- **Legacy Material System**: Migrate to Substrate for new projects
- **Old PCG API**: Use new production-ready PCG API (5.7+)
## Verified Sources
- Official docs: https://docs.unrealengine.com/5.7/
- UE 5.7 release notes: https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-7-release-notes
- What's new in 5.7: https://dev.epicgames.com/documentation/en-us/unreal-engine/whats-new
- UE 5.7 announcement: https://www.unrealengine.com/en-US/news/unreal-engine-5-7-is-now-available
- UE 5.5 blog: https://www.unrealengine.com/en-US/blog/unreal-engine-5-5-is-now-available
- Migration guides: https://docs.unrealengine.com/5.7/en-US/upgrading-projects/

View File

@@ -0,0 +1,150 @@
# Unreal Engine 5.7 — Breaking Changes
**Last verified:** 2026-02-13
This document tracks breaking API changes and behavioral differences between Unreal Engine 5.3
(likely in model training) and Unreal Engine 5.7 (current version). Organized by risk level.
## HIGH RISK — Will Break Existing Code
### Substrate Material System (Production-Ready in 5.7)
**Versions:** UE 5.5+ (experimental), 5.7 (production-ready)
Substrate replaces the legacy material system with a modular, physically accurate framework.
```cpp
// ❌ OLD: Legacy material nodes (still work but deprecated)
// Standard material graph with Base Color, Metallic, Roughness, etc.
// ✅ NEW: Substrate material layers
// Use Substrate nodes: Substrate Slab, Substrate Blend, etc.
// Modular material authoring with true physical accuracy
```
**Migration:** Enable Substrate in `Project Settings > Engine > Substrate` and rebuild materials using Substrate nodes.
---
### PCG (Procedural Content Generation) API Overhaul
**Versions:** UE 5.7 (production-ready)
PCG framework reached production-ready status with major API changes.
```cpp
// ❌ OLD: Experimental PCG API (pre-5.7)
// Old node types, unstable API
// ✅ NEW: Production PCG API (5.7+)
// Use FPCGContext, IPCGElement, new node types
// Stable API, production-ready workflow
```
**Migration:** Follow PCG migration guide in 5.7 docs. Expect significant refactoring for experimental PCG code.
---
### Megalights Rendering System
**Versions:** UE 5.5+
New lighting system supports millions of dynamic lights.
```cpp
// ❌ OLD: Limited dynamic lights (clustered forward shading)
// Max ~100-200 dynamic lights before performance degrades
// ✅ NEW: Megalights (5.5+)
// Millions of dynamic lights with minimal performance cost
// Enable: Project Settings > Engine > Rendering > Megalights
```
**Migration:** No code changes needed, but lighting behavior may differ. Test scenes after enabling.
---
## MEDIUM RISK — Behavioral Changes
### Enhanced Input System (Now Default)
**Versions:** UE 5.1+ (recommended), 5.7 (default)
Enhanced Input is now the default input system.
```cpp
// ❌ OLD: Legacy input bindings (deprecated)
InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
// ✅ NEW: Enhanced Input
SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent);
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
}
```
**Migration:** Replace legacy input bindings with Enhanced Input actions.
---
### Nanite Default Enabled
**Versions:** UE 5.0+ (optional), 5.7 (encouraged)
Nanite virtualized geometry is now the recommended workflow for static meshes.
```cpp
// Enable Nanite on static mesh:
// Static Mesh Editor > Details > Nanite Settings > Enable Nanite Support
```
**Migration:** Convert high-poly meshes to Nanite. Test performance on target platforms.
---
## LOW RISK — Deprecations (Still Functional)
### Legacy Material System
**Status:** Deprecated but supported
**Replacement:** Substrate Material System
Legacy materials still work, but Substrate is recommended for new projects.
---
### Old World Partition (UE4 Style)
**Status:** Deprecated
**Replacement:** World Partition (UE5+)
Use UE5's World Partition system for large worlds.
---
## Platform-Specific Breaking Changes
### Windows
- **UE 5.7**: DirectX 12 is now default (was DX11 in older versions)
- Update shaders for DX12 compatibility
### macOS
- **UE 5.5+**: Metal 3 required (minimum macOS 13)
### Mobile
- **UE 5.7**: Minimum Android API level raised to 26 (Android 8.0)
- Minimum iOS deployment target raised to iOS 14
---
## Migration Checklist
When upgrading from UE 5.3 to UE 5.7:
- [ ] Review Substrate materials (convert if ready for new system)
- [ ] Audit PCG usage (update to production API if using experimental)
- [ ] Test Megalights performance (enable and benchmark)
- [ ] Migrate legacy input to Enhanced Input
- [ ] Convert high-poly meshes to Nanite
- [ ] Update shaders for DX12 (Windows) or Metal 3 (macOS)
- [ ] Verify minimum platform versions (Android 8.0, iOS 14)
- [ ] Test Lumen and Nanite performance on target hardware
---
**Sources:**
- https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-7-release-notes
- https://dev.epicgames.com/documentation/en-us/unreal-engine/upgrading-projects-to-newer-versions-of-unreal-engine

View File

@@ -0,0 +1,340 @@
# Unreal Engine 5.7 — Current Best Practices
**Last verified:** 2026-02-13
Modern UE5 patterns that may not be in the LLM's training data.
These are production-ready recommendations as of UE 5.7.
---
## Project Setup
### Use UE 5.7 for New Projects
- Latest features: Megalights, production-ready Substrate and PCG
- Better performance and stability
### Choose the Right Rendering Features
- **Lumen**: Real-time global illumination (RECOMMENDED for most projects)
- **Nanite**: Virtualized geometry for high-poly meshes (RECOMMENDED for detailed environments)
- **Megalights**: Millions of dynamic lights (RECOMMENDED for complex lighting)
- **Substrate**: Modular material system (RECOMMENDED for new projects)
---
## C++ Coding
### Use Modern C++ Features (C++20 in UE5.7)
```cpp
// ✅ Use TObjectPtr<T> (UE5 type-safe pointers)
UPROPERTY()
TObjectPtr<UStaticMeshComponent> MeshComp;
// ✅ Structured bindings
if (auto [bSuccess, Value] = TryGetValue(); bSuccess) {
// Use Value
}
// ✅ Concepts and constraints (C++20)
template<typename T>
concept Damageable = requires(T t, float damage) {
{ t.TakeDamage(damage) } -> std::same_as<void>;
};
```
### Use UPROPERTY() for Garbage Collection
```cpp
// ✅ UPROPERTY ensures GC doesn't delete this
UPROPERTY()
TObjectPtr<AActor> MyActor;
// ❌ Raw pointers can become dangling
AActor* MyActor; // Dangerous! May be garbage collected
```
### Use UFUNCTION() for Blueprint Exposure
```cpp
// ✅ Callable from Blueprint
UFUNCTION(BlueprintCallable, Category="Combat")
void TakeDamage(float Damage);
// ✅ Implementable in Blueprint
UFUNCTION(BlueprintImplementableEvent, Category="Combat")
void OnDeath();
```
---
## Blueprint Best Practices
### Use Blueprint vs C++
- **C++**: Core gameplay systems, performance-critical code, low-level engine interaction
- **Blueprint**: Rapid prototyping, content creation, data-driven logic, designer workflows
### Blueprint Performance Tips
```cpp
// ✅ Use Event Tick sparingly (expensive)
// Prefer timers or events
// ✅ Use Blueprint Nativization (Blueprints → C++)
// Project Settings > Packaging > Blueprint Nativization
// ✅ Cache frequently accessed components
// Don't call GetComponent every tick
```
---
## Rendering (UE 5.7)
### Use Lumen for Global Illumination
```cpp
// Enable: Project Settings > Engine > Rendering > Dynamic Global Illumination Method = Lumen
// Real-time GI, no lightmap baking needed (RECOMMENDED)
```
### Use Nanite for High-Poly Meshes
```cpp
// Enable on Static Mesh: Details > Nanite Settings > Enable Nanite Support
// Automatically LODs millions of triangles (RECOMMENDED for detailed meshes)
```
### Use Megalights for Complex Lighting (UE 5.5+)
```cpp
// Enable: Project Settings > Engine > Rendering > Megalights = Enabled
// Supports millions of dynamic lights with minimal cost
```
### Use Substrate Materials (Production-Ready in 5.7)
```cpp
// Enable: Project Settings > Engine > Substrate > Enable Substrate
// Modular, physically accurate materials (RECOMMENDED for new projects)
```
---
## Enhanced Input System
### Setup Enhanced Input
```cpp
// 1. Create Input Action (IA_Jump)
// 2. Create Input Mapping Context (IMC_Default)
// 3. Add mapping: IA_Jump → Space Bar
// C++ Setup:
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
void AMyCharacter::BeginPlay() {
Super::BeginPlay();
if (APlayerController* PC = Cast<APlayerController>(GetController())) {
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer())) {
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent);
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
}
void AMyCharacter::Move(const FInputActionValue& Value) {
FVector2D MoveVector = Value.Get<FVector2D>();
AddMovementInput(GetActorForwardVector(), MoveVector.Y);
AddMovementInput(GetActorRightVector(), MoveVector.X);
}
```
---
## Gameplay Ability System (GAS)
### Use GAS for Complex Gameplay
```cpp
// ✅ Use GAS for: Abilities, buffs, damage calculation, cooldowns
// Modular, scalable, multiplayer-ready
// Install: Enable "Gameplay Abilities" plugin
// Example Ability:
UCLASS()
class UGA_Fireball : public UGameplayAbility {
GENERATED_BODY()
public:
virtual void ActivateAbility(...) override {
// Ability logic
SpawnFireball();
CommitAbility(); // Commit cost/cooldown
}
};
```
---
## World Partition (Large Worlds)
### Use World Partition for Open Worlds
```cpp
// Enable: World Settings > Enable World Partition
// Automatically streams world cells based on player location
// Data Layers: Organize content (e.g., "Gameplay", "Audio", "Lighting")
// Runtime Data Layers: Load/unload at runtime
```
---
## Niagara (VFX)
### Use Niagara (Not Cascade)
```cpp
// Create: Content Browser > Right Click > FX > Niagara System
// GPU-accelerated, node-based particle system (RECOMMENDED)
// Spawn particles:
UNiagaraComponent* NiagaraComp = UNiagaraFunctionLibrary::SpawnSystemAtLocation(
GetWorld(),
ExplosionSystem,
GetActorLocation()
);
```
---
## MetaSounds (Audio)
### Use MetaSounds for Procedural Audio
```cpp
// Create: Content Browser > Right Click > Sounds > MetaSound Source
// Node-based audio, replaces Sound Cue for complex logic (RECOMMENDED)
// Play MetaSound:
UAudioComponent* AudioComp = UGameplayStatics::SpawnSound2D(
GetWorld(),
MetaSoundSource
);
```
---
## Replication (Multiplayer)
### Server-Authoritative Pattern
```cpp
// ✅ Client sends input, server validates and replicates
UFUNCTION(Server, Reliable)
void Server_Move(FVector Direction);
void AMyCharacter::Server_Move_Implementation(FVector Direction) {
// Server validates and applies movement
AddMovementInput(Direction);
}
// ✅ Replicate important state
UPROPERTY(Replicated)
int32 Health;
void AMyCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyCharacter, Health);
}
```
---
## Performance Optimization
### Use Object Pooling
```cpp
// ✅ Reuse objects instead of Spawn/Destroy
TArray<AActor*> ProjectilePool;
AActor* GetPooledProjectile() {
for (AActor* Proj : ProjectilePool) {
if (!Proj->IsActive()) {
Proj->SetActive(true);
return Proj;
}
}
// Pool exhausted, spawn new
return SpawnNewProjectile();
}
```
### Use Instanced Static Meshes
```cpp
// ✅ Hierarchical Instanced Static Mesh Component (HISM)
// Render thousands of identical meshes in one draw call
UHierarchicalInstancedStaticMeshComponent* HISM = CreateDefaultSubobject<UHierarchicalInstancedStaticMeshComponent>(TEXT("Trees"));
for (int i = 0; i < 1000; i++) {
HISM->AddInstance(FTransform(RandomLocation));
}
```
---
## Debugging
### Use Logging
```cpp
// ✅ Structured logging
UE_LOG(LogTemp, Warning, TEXT("Player health: %d"), Health);
// Custom log category
DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);
DEFINE_LOG_CATEGORY(LogMyGame);
UE_LOG(LogMyGame, Error, TEXT("Critical error!"));
```
### Use Visual Logger
```cpp
// ✅ Visual debugging
#include "VisualLogger/VisualLogger.h"
UE_VLOG_SEGMENT(this, LogTemp, Log, StartPos, EndPos, FColor::Red, TEXT("Raycast"));
UE_VLOG_LOCATION(this, LogTemp, Log, TargetLocation, 50.f, FColor::Green, TEXT("Target"));
```
---
## Summary: UE 5.7 Recommended Stack
| Feature | Use This (2026) | Notes |
|---------|------------------|-------|
| **Lighting** | Lumen + Megalights | Real-time GI, millions of lights |
| **Geometry** | Nanite | High-poly meshes, automatic LOD |
| **Materials** | Substrate | Modular, physically accurate |
| **Input** | Enhanced Input | Rebindable, modular |
| **VFX** | Niagara | GPU-accelerated |
| **Audio** | MetaSounds | Procedural audio |
| **World Streaming** | World Partition | Large open worlds |
| **Gameplay** | Gameplay Ability System | Complex abilities, buffs |
---
**Sources:**
- https://docs.unrealengine.com/5.7/en-US/
- https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-7-release-notes

View File

@@ -0,0 +1,170 @@
# Unreal Engine 5.7 — Deprecated APIs
**Last verified:** 2026-02-13
Quick lookup table for deprecated APIs and their replacements.
Format: **Don't use X****Use Y instead**
---
## Input
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `InputComponent->BindAction()` | Enhanced Input `BindAction()` | New input system |
| `InputComponent->BindAxis()` | Enhanced Input `BindAxis()` | New input system |
| `PlayerController->GetInputAxisValue()` | Enhanced Input Action Values | New input system |
**Migration:** Install Enhanced Input plugin, create Input Actions and Input Mapping Contexts.
---
## Rendering
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Legacy material nodes | Substrate material nodes | Substrate is production-ready in 5.7 |
| Forward shading (default) | Deferred + Lumen | Lumen is default in UE5 |
| Old lighting workflow | Lumen Global Illumination | Real-time GI |
---
## World Building
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| UE4 World Composition | World Partition (UE5) | Streaming large worlds |
| Level Streaming Volumes | World Partition Data Layers | Better level streaming |
---
## Animation
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Old animation retargeting | IK Rig + IK Retargeter | UE5 retargeting system |
| Legacy control rig | Control Rig 2.0 | Production-ready rigging |
---
## Gameplay
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `UGameplayStatics::LoadStreamLevel()` | World Partition streaming | Use Data Layers |
| Hardcoded input bindings | Enhanced Input system | Rebindable, modular input |
---
## Niagara (VFX)
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Cascade particle system | Niagara | Cascade is fully deprecated |
---
## Audio
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| Old audio mixer | MetaSounds | Procedural audio system |
| Sound Cue (for complex logic) | MetaSounds | More powerful, node-based |
---
## Networking
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `DOREPLIFETIME()` (basic) | `DOREPLIFETIME_CONDITION()` | Conditional replication for optimization |
---
## C++ Scripting
| Deprecated | Replacement | Notes |
|------------|-------------|-------|
| `TSharedPtr<T>` for UObjects | `TObjectPtr<T>` | UE5 type-safe pointers |
| Manual RTTI checks | `Cast<T>()` / `IsA<T>()` | Type-safe casting |
---
## Quick Migration Patterns
### Input Example
```cpp
// ❌ Deprecated
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
}
// ✅ Enhanced Input
#include "EnhancedInputComponent.h"
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EIC) {
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
}
}
```
### Material Example
```cpp
// ❌ Deprecated: Legacy material
// Use standard material graph (still works but not recommended)
// ✅ Substrate Material
// Enable: Project Settings > Engine > Substrate > Enable Substrate
// Use Substrate nodes in material editor
```
### World Partition Example
```cpp
// ❌ Deprecated: Level streaming volumes
// Load/unload levels manually
// ✅ World Partition
// Enable: World Settings > Enable World Partition
// Use Data Layers for streaming
```
### Particle System Example
```cpp
// ❌ Deprecated: Cascade
UParticleSystemComponent* PSC = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("Particles"));
// ✅ Niagara
UNiagaraComponent* NiagaraComp = CreateDefaultSubobject<UNiagaraComponent>(TEXT("Niagara"));
```
### Audio Example
```cpp
// ❌ Deprecated: Sound Cue for complex logic
// Use Sound Cue editor nodes
// ✅ MetaSounds
// Create MetaSound Source asset, use node-based audio
```
---
## Summary: UE 5.7 Tech Stack
| Feature | Use This (2026) | Avoid This (Legacy) |
|---------|------------------|----------------------|
| **Input** | Enhanced Input | Legacy Input Bindings |
| **Materials** | Substrate | Legacy Material System |
| **Lighting** | Lumen + Megalights | Lightmaps + Limited Lights |
| **Particles** | Niagara | Cascade |
| **Audio** | MetaSounds | Sound Cue (for logic) |
| **World Streaming** | World Partition | World Composition |
| **Animation Retarget** | IK Rig + Retargeter | Old Retargeting |
| **Geometry** | Nanite (high-poly) | Standard Static Mesh LODs |
---
**Sources:**
- https://docs.unrealengine.com/5.7/en-US/deprecated-and-removed-features/
- https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-7-release-notes

View File

@@ -0,0 +1,292 @@
# Unreal Engine 5.7 — Animation Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 animation authoring improvements, Control Rig 2.0
---
## Overview
UE 5.7 animation systems:
- **Animation Blueprint**: State machine-based animation logic
- **Control Rig**: Runtime procedural animation (production-ready in UE5)
- **IK Rig + Retargeter**: Modern retargeting system
- **Sequencer**: Cinematic animation
---
## Animation Blueprint
### Create Animation Blueprint
1. Content Browser > Right Click > Animation > Animation Blueprint
2. Select parent class: `AnimInstance`
3. Select skeleton
### Animation State Machine
```cpp
// In Animation Blueprint Event Graph:
// - State Machine drives animation states (Idle, Walk, Run, Jump)
// - Blend Spaces for directional movement
// Access in C++:
UAnimInstance* AnimInstance = Mesh->GetAnimInstance();
AnimInstance->Montage_Play(AttackMontage);
```
---
## Play Animation Montages
### Animation Montage
```cpp
// Play montage
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
AnimInstance->Montage_Play(AttackMontage, 1.0f);
// Stop montage
AnimInstance->Montage_Stop(0.2f, AttackMontage);
// Check if montage is playing
bool bIsPlaying = AnimInstance->Montage_IsPlaying(AttackMontage);
```
### Montage Notify Events
```cpp
// Add notify event in Animation Montage (right-click timeline > Add Notify > New Notify)
// Implement in C++:
UCLASS()
class UMyAnimInstance : public UAnimInstance {
GENERATED_BODY()
public:
UFUNCTION()
void AnimNotify_AttackHit() {
// Called when notify is reached
DealDamage();
}
};
```
---
## Blend Spaces
### 1D Blend Space (Speed Blending)
```cpp
// Create: Content Browser > Animation > Blend Space 1D
// Horizontal Axis: Speed (0 = Idle, 1 = Walk, 2 = Run)
// Add animations at key points
// Use in Anim Blueprint:
// - Get speed from character
// - Feed into Blend Space
```
### 2D Blend Space (Directional Movement)
```cpp
// Create: Content Browser > Animation > Blend Space
// Horizontal Axis: Direction X (-1 to 1)
// Vertical Axis: Direction Y (-1 to 1)
// Place animations (Fwd, Back, Left, Right, diagonal)
```
---
## Control Rig (Procedural Animation)
### Create Control Rig
1. Content Browser > Animation > Control Rig
2. Select skeleton
3. Build rig hierarchy (bones, controls, IK)
### Use Control Rig in Animation Blueprint
```cpp
// Add "Control Rig" node to Anim Blueprint
// Assign Control Rig asset
// Procedurally modify bones at runtime
```
### Control Rig in C++
```cpp
// Get control rig component
UControlRig* ControlRig = /* Get from animation instance */;
// Set control value
ControlRig->SetControlValue<FVector>(TEXT("IK_Hand_R"), TargetLocation);
```
---
## IK Rig & Retargeting (UE5)
### Create IK Rig
1. Content Browser > Animation > IK Rig
2. Select skeleton
3. Add IK goals (hands, feet)
4. Set up solver chains
### Retarget Animations
1. Create IK Rig for source skeleton
2. Create IK Rig for target skeleton
3. Create IK Retargeter asset
4. Assign source and target IK Rigs
5. Batch retarget animations
### Retargeting in C++
```cpp
// Retargeting is primarily editor-based
// Animations are retargeted once, then used normally
```
---
## Animation Notify States
### Custom Notify State (Duration-Based Events)
```cpp
UCLASS()
class UAnimNotifyState_Invulnerable : public UAnimNotifyState {
GENERATED_BODY()
public:
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override {
// Start invulnerability
AMyCharacter* Character = Cast<AMyCharacter>(MeshComp->GetOwner());
Character->bIsInvulnerable = true;
}
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override {
// End invulnerability
AMyCharacter* Character = Cast<AMyCharacter>(MeshComp->GetOwner());
Character->bIsInvulnerable = false;
}
};
```
---
## Skeletal Mesh & Sockets
### Attach Objects to Sockets
```cpp
// Create socket in Skeletal Mesh Editor (Skeleton Tree > Add Socket)
// Attach component to socket
UStaticMeshComponent* Weapon = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Weapon"));
Weapon->SetupAttachment(GetMesh(), TEXT("hand_r_socket"));
```
---
## Animation Curves
### Use Animation Curves
```cpp
// Add curve to animation:
// Animation Editor > Curves > Add Curve
// Read curve value in Anim Blueprint or C++:
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
float CurveValue = AnimInstance->GetCurveValue(TEXT("MyCurve"));
```
---
## Root Motion
### Enable Root Motion
```cpp
// In Animation Sequence: Asset Details > Root Motion > Enable Root Motion
// In Character class:
GetCharacterMovement()->bAllowPhysicsRotationDuringAnimRootMotion = true;
```
---
## Animation Layers (Linked Anim Graphs)
### Use Linked Anim Layers
```cpp
// Create separate Anim Blueprints for layers (e.g., upper body, lower body)
// Link in main Anim Blueprint: Add "Linked Anim Graph" node
// Dynamically switch layers:
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
AnimInstance->LinkAnimClassLayers(NewLayerClass);
```
---
## Sequencer (Cinematic Animation)
### Create Sequence
1. Content Browser > Cinematics > Level Sequence
2. Add tracks: Camera, Character, Animation, etc.
### Play Sequence from C++
```cpp
#include "LevelSequenceActor.h"
#include "LevelSequencePlayer.h"
ALevelSequenceActor* SequenceActor = /* Spawn or find in level */;
SequenceActor->GetSequencePlayer()->Play();
```
---
## Performance Tips
### Animation Optimization
```cpp
// LOD (Level of Detail) for skeletal meshes
// Reduce bone count for distant characters
// Anim Blueprint optimization:
// - Use "Anim Node Relevancy" (skip updates when not visible)
// - Disable updates when off-screen:
GetMesh()->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::OnlyTickPoseWhenRendered;
```
---
## Debugging
### Animation Debug Visualization
```cpp
// Console commands:
// showdebug animation - Show animation state info
// a.VisualizeSkeletalMeshBones 1 - Show skeleton bones
// Draw debug bones:
DrawDebugCoordinateSystem(GetWorld(), BoneLocation, BoneRotation, 50.0f, false, -1.0f, 0, 2.0f);
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/animation-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/control-rig-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/ik-rig-in-unreal-engine/

View File

@@ -0,0 +1,289 @@
# Unreal Engine 5.7 — Audio Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 MetaSounds production-ready
---
## Overview
UE 5.7 audio systems:
- **MetaSounds**: Node-based procedural audio (RECOMMENDED, production-ready)
- **Sound Cues**: Legacy node-based audio (use for simple cases)
- **Audio Component**: Play sounds on actors
---
## Basic Audio Playback
### Play Sound at Location
```cpp
#include "Kismet/GameplayStatics.h"
// ✅ Play 2D sound (no spatialization)
UGameplayStatics::PlaySound2D(GetWorld(), ExplosionSound);
// ✅ Play sound at location (3D spatial audio)
UGameplayStatics::PlaySoundAtLocation(GetWorld(), ExplosionSound, GetActorLocation());
// ✅ With volume and pitch
UGameplayStatics::PlaySoundAtLocation(GetWorld(), ExplosionSound, GetActorLocation(), 0.7f, 1.2f);
```
---
## Audio Component
### Audio Component (Persistent Sound)
```cpp
// Create audio component
UAudioComponent* AudioComp = CreateDefaultSubobject<UAudioComponent>(TEXT("Audio"));
AudioComp->SetupAttachment(RootComponent);
AudioComp->SetSound(LoopingAmbience);
// Play/Stop
AudioComp->Play();
AudioComp->Stop();
// Fade in/out
AudioComp->FadeIn(2.0f); // 2 seconds
AudioComp->FadeOut(1.5f, 0.0f); // 1.5s to volume 0
// Adjust volume/pitch
AudioComp->SetVolumeMultiplier(0.5f);
AudioComp->SetPitchMultiplier(1.2f);
```
---
## 3D Spatial Audio
### Attenuation Settings
```cpp
// Create Sound Attenuation asset:
// Content Browser > Sounds > Sound Attenuation
// Configure:
// - Attenuation Shape: Sphere, Capsule, Box, Cone
// - Falloff Distance: Distance where sound becomes inaudible
// - Attenuation Function: Linear, Logarithmic, Inverse, etc.
// Assign in C++:
AudioComp->AttenuationSettings = AttenuationAsset;
```
### Attenuation Override in Code
```cpp
FSoundAttenuationSettings AttenuationOverride;
AttenuationOverride.AttenuationShape = EAttenuationShape::Sphere;
AttenuationOverride.FalloffDistance = 1000.0f;
AttenuationOverride.AttenuationShapeExtents = FVector(1000.0f);
AudioComp->AttenuationOverrides = AttenuationOverride;
AudioComp->bOverrideAttenuation = true;
```
---
## MetaSounds (Procedural Audio)
### Create MetaSound Source
1. Content Browser > Sounds > MetaSound Source
2. Open MetaSound editor
3. Build node graph:
- **Inputs**: Triggers, parameters
- **Generators**: Oscillators, noise, samples
- **Modulators**: Envelopes, LFOs
- **Effects**: Filters, reverb, delay
- **Output**: Audio output
### Play MetaSound
```cpp
// Play MetaSound like any sound
UGameplayStatics::PlaySound2D(GetWorld(), MetaSoundSource);
// Or with Audio Component
AudioComp->SetSound(MetaSoundSource);
AudioComp->Play();
```
### Set MetaSound Parameters
```cpp
// Define parameter in MetaSound (Input node with exposed parameter)
// Set parameter in C++:
AudioComp->SetFloatParameter(FName("Volume"), 0.8f);
AudioComp->SetIntParameter(FName("OctaveShift"), 2);
AudioComp->SetBoolParameter(FName("EnableReverb"), true);
```
---
## Sound Cues (Legacy)
### Create Sound Cue
1. Content Browser > Sounds > Sound Cue
2. Open Sound Cue editor
3. Add nodes: Random, Modulator, Mixer, etc.
### Use Sound Cue
```cpp
// Play like any sound
UGameplayStatics::PlaySound2D(GetWorld(), SoundCue);
```
---
## Sound Classes & Sound Mixes
### Sound Class (Volume Groups)
```cpp
// Create Sound Class: Content Browser > Sounds > Sound Class
// Hierarchy: Master > Music, SFX, Dialogue
// Assign to sound asset:
// Sound Wave > Sound Class = SFX
// Set volume in C++:
UAudioSettings* AudioSettings = GetMutableDefault<UAudioSettings>();
// Configure via Sound Class hierarchy
```
### Sound Mix (Dynamic Mixing)
```cpp
// Create Sound Mix asset
// Define adjustments: Lower music during dialogue, etc.
// Push sound mix
UGameplayStatics::PushSoundMixModifier(GetWorld(), DuckedMusicMix);
// Pop sound mix
UGameplayStatics::PopSoundMixModifier(GetWorld(), DuckedMusicMix);
```
---
## Audio Occlusion & Reverb
### Audio Occlusion (Walls Block Sound)
```cpp
// Enable in Audio Component:
AudioComp->bEnableOcclusion = true;
// Requires geometry with collision
```
### Reverb Volumes
```cpp
// Add Audio Volume to level (Volumes > Audio Volume)
// Configure reverb settings in Details panel
// Audio component automatically picks up reverb when inside volume
```
---
## Common Patterns
### Footstep Sounds (Random Variation)
```cpp
// Use Sound Cue with Random node, or:
UPROPERTY(EditAnywhere, Category = "Audio")
TArray<TObjectPtr<USoundBase>> FootstepSounds;
void PlayFootstep() {
int32 Index = FMath::RandRange(0, FootstepSounds.Num() - 1);
UGameplayStatics::PlaySoundAtLocation(GetWorld(), FootstepSounds[Index], GetActorLocation());
}
```
### Music Crossfade
```cpp
UAudioComponent* MusicA;
UAudioComponent* MusicB;
void CrossfadeMusic(float Duration) {
MusicA->FadeOut(Duration, 0.0f);
MusicB->FadeIn(Duration);
}
```
### Check if Sound is Playing
```cpp
if (AudioComp->IsPlaying()) {
// Sound is playing
}
```
---
## Audio Concurrency
### Limit Concurrent Sounds
```cpp
// Create Sound Concurrency asset:
// Content Browser > Sounds > Sound Concurrency
// Configure:
// - Max Count: Maximum instances of this sound
// - Resolution Rule: Stop Oldest, Stop Quietest, etc.
// Assign to sound:
// Sound Wave > Concurrency Settings
```
---
## Performance Tips
### Audio Optimization
```cpp
// Compression settings (Sound Wave asset):
// - Compression Quality: 40 (balance quality/size)
// - Streaming: Enable for large files (music)
// Reduce audio mixing cost:
// - Limit concurrent sounds via Sound Concurrency
// - Use simple attenuation shapes
// Disable audio for distant actors:
if (Distance > MaxAudibleDistance) {
AudioComp->Stop();
}
```
---
## Debugging
### Audio Debug Commands
```cpp
// Console commands:
// au.Debug.Sounds 1 - Show active sounds
// au.3dVisualize.Enabled 1 - Visualize 3D audio
// stat soundwaves - Show sound statistics
// stat soundmixes - Show active sound mixes
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/audio-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/metasounds-in-unreal-engine/

View File

@@ -0,0 +1,288 @@
# Unreal Engine 5.7 — Input Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 uses Enhanced Input as default (legacy input deprecated)
---
## Overview
UE 5.7 input systems:
- **Enhanced Input** (RECOMMENDED, default in UE5): Modular, rebindable, context-based
- **Legacy Input**: Deprecated, avoid for new projects
---
## Enhanced Input System
### Setup Enhanced Input
1. **Enable Plugin**: `Edit > Plugins > Enhanced Input` (enabled by default in UE5)
2. **Project Settings**: `Engine > Input > Default Classes > Default Player Input Class = EnhancedPlayerInput`
---
### Create Input Actions
1. Content Browser > Input > Input Action
2. Name it (e.g., `IA_Jump`, `IA_Move`)
3. Configure:
- **Value Type**: Digital (bool), Axis1D (float), Axis2D (Vector2D), Axis3D (Vector)
Example Input Actions:
- `IA_Jump`: Digital (bool)
- `IA_Move`: Axis2D (Vector2D)
- `IA_Look`: Axis2D (Vector2D)
- `IA_Fire`: Digital (bool)
---
### Create Input Mapping Context
1. Content Browser > Input > Input Mapping Context
2. Name it (e.g., `IMC_Default`)
3. Add mappings:
- `IA_Jump` → Space Bar
- `IA_Move` → W/A/S/D keys (combine X/Y)
- `IA_Look` → Mouse XY
- `IA_Fire` → Left Mouse Button
---
### Bind Input in C++
```cpp
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputActionValue.h"
class AMyCharacter : public ACharacter {
public:
// Input Actions (assign in Blueprint)
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> MoveAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> LookAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> JumpAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputMappingContext> DefaultMappingContext;
protected:
virtual void BeginPlay() override {
Super::BeginPlay();
// Add Input Mapping Context
if (APlayerController* PC = Cast<APlayerController>(Controller)) {
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer())) {
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override {
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EIC) {
// Bind actions
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
EIC->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
EIC->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyCharacter::Look);
}
}
void Move(const FInputActionValue& Value) {
FVector2D MoveVector = Value.Get<FVector2D>();
if (Controller) {
AddMovementInput(GetActorForwardVector(), MoveVector.Y);
AddMovementInput(GetActorRightVector(), MoveVector.X);
}
}
void Look(const FInputActionValue& Value) {
FVector2D LookVector = Value.Get<FVector2D>();
if (Controller) {
AddControllerYawInput(LookVector.X);
AddControllerPitchInput(LookVector.Y);
}
}
};
```
---
## Input Triggers
### Trigger Types
Input Actions can have triggers to control when they fire:
- **Pressed**: When input starts
- **Released**: When input ends
- **Hold**: Hold for duration
- **Tap**: Quick press
- **Pulse**: Repeated firing while held
### Add Trigger in Editor
1. Open Input Action asset
2. Triggers > Add > Select trigger type (e.g., `Hold`)
3. Configure (e.g., Hold Time = 0.5s)
---
## Input Modifiers
### Modifier Types
Modifiers transform input values:
- **Negate**: Flip sign (-1 ↔ 1)
- **Dead Zone**: Ignore small inputs
- **Scalar**: Multiply by value
- **Smooth**: Smoothing over time
### Add Modifier in Editor
1. Open Input Action asset
2. Modifiers > Add > Select modifier (e.g., `Negate`)
3. Configure
---
## Input Mapping Contexts (Context Switching)
### Multiple Contexts
```cpp
// Define contexts
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputMappingContext> DefaultContext;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputMappingContext> VehicleContext;
// Switch context
void EnterVehicle() {
if (APlayerController* PC = Cast<APlayerController>(Controller)) {
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer())) {
Subsystem->RemoveMappingContext(DefaultContext);
Subsystem->AddMappingContext(VehicleContext, 0);
}
}
}
```
---
## Legacy Input (Deprecated)
### Legacy Input Bindings
```cpp
// ❌ DEPRECATED: Do not use for new projects
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
// Legacy action binding
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
// Legacy axis binding
PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
}
void MoveForward(float Value) {
AddMovementInput(GetActorForwardVector(), Value);
}
```
**Migration:** Use Enhanced Input instead.
---
## Gamepad Input
### Gamepad with Enhanced Input
```cpp
// Input Mapping Context:
// - IA_Move → Gamepad Left Thumbstick
// - IA_Look → Gamepad Right Thumbstick
// - IA_Jump → Gamepad Face Button Bottom (A/Cross)
// No code changes needed, just add gamepad mappings to Input Mapping Context
```
---
## Touch Input (Mobile)
### Touch Input with Enhanced Input
```cpp
// Input Mapping Context:
// - IA_Move → Touch (virtual thumbstick)
// - IA_Look → Touch (swipe)
// Use Touch Interface asset for virtual controls
```
---
## Rebinding Input at Runtime
### Change Key Mapping
```cpp
#include "PlayerMappableInputConfig.h"
// Get subsystem
UEnhancedInputLocalPlayerSubsystem* Subsystem = /* Get subsystem */;
// Get player mappable keys
FPlayerMappableKeySlot KeySlot = FPlayerMappableKeySlot(/*..*/);
FKey NewKey = EKeys::F; // Rebind to F key
// Apply new mapping
Subsystem->AddPlayerMappedKey(/*..*/);
```
---
## Input Debugging
### Debug Input
```cpp
// Console commands:
// showdebug input - Show input debug info
// Log input values:
UE_LOG(LogTemp, Warning, TEXT("Move Input: %s"), *MoveVector.ToString());
```
---
## Common Patterns
### Check if Key Pressed (Quick & Dirty)
```cpp
// For debugging only (not recommended for gameplay)
if (GetWorld()->GetFirstPlayerController()->IsInputKeyDown(EKeys::SpaceBar)) {
// Space bar is down
}
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/enhanced-input-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/enhanced-input-action-and-input-mapping-context-in-unreal-engine/

View File

@@ -0,0 +1,338 @@
# Unreal Engine 5.7 — Navigation Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 navigation improvements
---
## Overview
UE 5.7 navigation systems:
- **Nav Mesh**: Automatic pathfinding mesh for AI
- **AI Controller**: Controls AI movement and behavior
- **Behavior Trees**: AI decision-making (covered in AI module)
---
## Nav Mesh Setup
### Add Nav Mesh Bounds Volume
1. Place Actors > Volumes > Nav Mesh Bounds Volume
2. Scale to cover walkable areas
3. Press `P` to toggle Nav Mesh visualization (green overlay)
### Nav Mesh Settings
```cpp
// Project Settings > Engine > Navigation System
// - Generate Navigation Only Around Navigation Invokers: Performance optimization
// - Auto Update Enabled: Rebuild NavMesh when geometry changes
```
---
## AI Controller & Movement
### Create AI Controller
```cpp
UCLASS()
class AEnemyAIController : public AAIController {
GENERATED_BODY()
public:
void BeginPlay() override {
Super::BeginPlay();
// Move to location
FVector TargetLocation = FVector(1000, 0, 0);
MoveToLocation(TargetLocation);
}
};
```
### Assign AI Controller to Pawn
```cpp
UCLASS()
class AEnemyCharacter : public ACharacter {
GENERATED_BODY()
public:
AEnemyCharacter() {
// ✅ Assign AI Controller class
AIControllerClass = AEnemyAIController::StaticClass();
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
}
};
```
---
## Basic AI Movement
### Move to Location
```cpp
AAIController* AIController = Cast<AAIController>(GetController());
if (AIController) {
FVector TargetLocation = FVector(1000, 0, 0);
EPathFollowingRequestResult::Type Result = AIController->MoveToLocation(TargetLocation);
if (Result == EPathFollowingRequestResult::RequestSuccessful) {
UE_LOG(LogTemp, Warning, TEXT("Moving to location"));
}
}
```
### Move to Actor
```cpp
AActor* Target = /* Get target actor */;
AIController->MoveToActor(Target, 100.0f); // Stop 100 units away
```
### Stop Movement
```cpp
AIController->StopMovement();
```
---
## Path Following Events
### On Move Completed
```cpp
UCLASS()
class AEnemyAIController : public AAIController {
GENERATED_BODY()
public:
void BeginPlay() override {
Super::BeginPlay();
// Bind to move completed event
ReceiveMoveCompleted.AddDynamic(this, &AEnemyAIController::OnMoveCompleted);
}
UFUNCTION()
void OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type Result) {
if (Result == EPathFollowingResult::Success) {
UE_LOG(LogTemp, Warning, TEXT("Reached destination"));
} else {
UE_LOG(LogTemp, Warning, TEXT("Failed to reach destination"));
}
}
};
```
---
## Pathfinding Queries
### Find Path to Location
```cpp
#include "NavigationSystem.h"
#include "NavigationPath.h"
UNavigationSystemV1* NavSys = UNavigationSystemV1::GetCurrent(GetWorld());
if (NavSys) {
FVector Start = GetActorLocation();
FVector End = TargetLocation;
FPathFindingQuery Query;
Query.StartLocation = Start;
Query.EndLocation = End;
Query.NavData = NavSys->GetDefaultNavDataInstance();
FPathFindingResult Result = NavSys->FindPathSync(Query);
if (Result.IsSuccessful()) {
UNavigationPath* NavPath = Result.Path.Get();
// Use path points: NavPath->GetPathPoints()
}
}
```
### Check if Location is Reachable
```cpp
UNavigationSystemV1* NavSys = UNavigationSystemV1::GetCurrent(GetWorld());
FNavLocation OutLocation;
bool bReachable = NavSys->ProjectPointToNavigation(TargetLocation, OutLocation);
if (bReachable) {
UE_LOG(LogTemp, Warning, TEXT("Location is reachable"));
}
```
---
## Nav Mesh Modifiers
### Nav Modifier Volume (Block/Allow Areas)
1. Place Actors > Volumes > Nav Modifier Volume
2. Configure Area Class (e.g., NavArea_Null to block, NavArea_LowHeight for crouching)
---
## Custom Nav Areas
### Create Custom Nav Area
```cpp
UCLASS()
class UNavArea_Jump : public UNavArea {
GENERATED_BODY()
public:
UNavArea_Jump() {
DefaultCost = 10.0f; // Higher cost = AI avoids unless necessary
FixedAreaEnteringCost = 100.0f; // One-time cost to enter
}
};
```
### Use Custom Nav Area
```cpp
// Assign to Nav Modifier Volume or geometry
```
---
## Nav Mesh Generation
### Rebuild Nav Mesh at Runtime
```cpp
UNavigationSystemV1* NavSys = UNavigationSystemV1::GetCurrent(GetWorld());
NavSys->Build(); // Rebuild entire NavMesh
```
### Dynamic Nav Mesh (Moving Obstacles)
```cpp
// Enable: Project Settings > Navigation System > Runtime Generation = Dynamic
// Mark actor as dynamic obstacle:
UStaticMeshComponent* Mesh = /* Get mesh */;
Mesh->SetCanEverAffectNavigation(true);
Mesh->bDynamicObstacle = true;
```
---
## Nav Links (Off-Mesh Connections)
### Nav Link Proxy (Jump, Teleport)
1. Place Actors > Navigation > Nav Link Proxy
2. Set up start and end points
3. Configure:
- **Direction**: One-way or bidirectional
- **Smart Link**: Animate character during traversal
---
## Crowd Management
### Detour Crowd (Avoid Overlapping)
```cpp
// Enable: Character Movement Component > Avoidance Enabled = true
// Configure avoidance group and flags
UCharacterMovementComponent* MoveComp = GetCharacterMovement();
MoveComp->SetAvoidanceGroup(1);
MoveComp->SetGroupsToAvoid(1);
MoveComp->SetAvoidanceEnabled(true);
```
---
## Performance Tips
### Nav Mesh Optimization
```cpp
// Reduce tile size for large worlds:
// Project Settings > Navigation System > Cell Size = 19 (default)
// Use Navigation Invokers for dynamic generation:
// Only generate NavMesh around players/important actors
```
---
## Debugging
### Visualize Nav Mesh
```cpp
// Console commands:
// show navigation - Toggle NavMesh visualization
// p - Toggle NavMesh (editor viewport)
// Draw debug path:
if (NavPath) {
for (int i = 0; i < NavPath->GetPathPoints().Num() - 1; i++) {
DrawDebugLine(GetWorld(), NavPath->GetPathPoints()[i], NavPath->GetPathPoints()[i + 1], FColor::Green, false, 5.0f, 0, 5.0f);
}
}
```
---
## Common Patterns
### Patrol Between Waypoints
```cpp
UPROPERTY(EditAnywhere, Category = "AI")
TArray<AActor*> PatrolPoints;
int32 CurrentPatrolIndex = 0;
void OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type Result) {
if (Result == EPathFollowingResult::Success) {
// Move to next waypoint
CurrentPatrolIndex = (CurrentPatrolIndex + 1) % PatrolPoints.Num();
MoveToActor(PatrolPoints[CurrentPatrolIndex]);
}
}
```
### Chase Player
```cpp
void Tick(float DeltaTime) {
Super::Tick(DeltaTime);
AAIController* AIController = Cast<AAIController>(GetController());
APawn* PlayerPawn = GetWorld()->GetFirstPlayerController()->GetPawn();
if (AIController && PlayerPawn) {
float Distance = FVector::Dist(GetActorLocation(), PlayerPawn->GetActorLocation());
if (Distance < 1000.0f) {
// Chase player
AIController->MoveToActor(PlayerPawn, 100.0f);
} else {
// Stop chasing
AIController->StopMovement();
}
}
}
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/navigation-system-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/ai-in-unreal-engine/

View File

@@ -0,0 +1,409 @@
# Unreal Engine 5.7 — Networking Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 networking improvements
---
## Overview
UE 5.7 networking:
- **Client-Server Architecture**: Server-authoritative (RECOMMENDED)
- **Replication**: Automatic state synchronization
- **RPCs (Remote Procedure Calls)**: Call functions across network
- **Relevancy**: Optimize bandwidth by only replicating relevant actors
---
## Basic Multiplayer Setup
### Enable Replication on Actor
```cpp
UCLASS()
class AMyActor : public AActor {
GENERATED_BODY()
public:
AMyActor() {
// ✅ Enable replication
bReplicates = true;
bAlwaysRelevant = true; // Always replicate to all clients
}
};
```
### Network Role Checks
```cpp
// Check role
if (HasAuthority()) {
// Running on server
}
if (GetLocalRole() == ROLE_AutonomousProxy) {
// This is the owning client (local player)
}
if (GetRemoteRole() == ROLE_SimulatedProxy) {
// This is a remote client (other players)
}
```
---
## Replicated Variables
### Basic Replication
```cpp
UPROPERTY(Replicated)
int32 Health;
UPROPERTY(Replicated)
FVector Position;
// ✅ Implement GetLifetimeReplicatedProps
void AMyActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyActor, Health);
DOREPLIFETIME(AMyActor, Position);
}
```
### Conditional Replication
```cpp
// Only replicate to owner
DOREPLIFETIME_CONDITION(AMyCharacter, Ammo, COND_OwnerOnly);
// Skip owner (replicate to everyone else)
DOREPLIFETIME_CONDITION(AMyCharacter, TeamID, COND_SkipOwner);
// Only when changed
DOREPLIFETIME_CONDITION(AMyCharacter, Score, COND_InitialOnly);
```
### RepNotify (Callback on Replication)
```cpp
UPROPERTY(ReplicatedUsing=OnRep_Health)
int32 Health;
UFUNCTION()
void OnRep_Health() {
// Called on clients when Health changes
UpdateHealthUI();
}
// Implement GetLifetimeReplicatedProps (same as above)
```
---
## RPCs (Remote Procedure Calls)
### Server RPC (Client → Server)
```cpp
// Client calls, server executes
UFUNCTION(Server, Reliable)
void Server_TakeDamage(int32 Damage);
void AMyCharacter::Server_TakeDamage_Implementation(int32 Damage) {
// Runs on server only
Health -= Damage;
if (Health <= 0) {
Server_Die();
}
}
bool AMyCharacter::Server_TakeDamage_Validate(int32 Damage) {
// Validate input (anti-cheat)
return Damage >= 0 && Damage <= 100;
}
```
### Client RPC (Server → Client)
```cpp
// Server calls, client executes
UFUNCTION(Client, Reliable)
void Client_ShowDeathScreen();
void AMyCharacter::Client_ShowDeathScreen_Implementation() {
// Runs on client only
ShowDeathUI();
}
```
### Multicast RPC (Server → All Clients)
```cpp
// Server calls, all clients execute
UFUNCTION(NetMulticast, Reliable)
void Multicast_PlayExplosion(FVector Location);
void AMyActor::Multicast_PlayExplosion_Implementation(FVector Location) {
// Runs on server and all clients
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplosionEffect, Location);
}
```
### RPC Reliability
```cpp
// Reliable: Guaranteed delivery (important events)
UFUNCTION(Server, Reliable)
void Server_FireWeapon();
// Unreliable: Best-effort delivery (frequent updates, position sync)
UFUNCTION(Server, Unreliable)
void Server_UpdateAim(FRotator AimRotation);
```
---
## Server-Authoritative Pattern (RECOMMENDED)
### Movement Example
```cpp
class AMyCharacter : public ACharacter {
UPROPERTY(Replicated)
FVector ServerPosition;
void Tick(float DeltaTime) override {
Super::Tick(DeltaTime);
if (GetLocalRole() == ROLE_AutonomousProxy) {
// Client: Send input to server
FVector Input = GetMovementInput();
Server_Move(Input);
// Client-side prediction (move locally)
AddMovementInput(Input);
}
if (HasAuthority()) {
// Server: Authoritative position
ServerPosition = GetActorLocation();
} else {
// Client: Interpolate toward server position
FVector NewPos = FMath::VInterpTo(GetActorLocation(), ServerPosition, DeltaTime, 5.0f);
SetActorLocation(NewPos);
}
}
UFUNCTION(Server, Unreliable)
void Server_Move(FVector Input);
void Server_Move_Implementation(FVector Input) {
// Server validates and applies movement
AddMovementInput(Input);
}
};
```
---
## Network Relevancy (Bandwidth Optimization)
### Custom Relevancy
```cpp
bool AMyActor::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const {
// Only replicate if within range
float Distance = FVector::Dist(SrcLocation, GetActorLocation());
return Distance < 5000.0f;
}
```
### Always Relevant Actors
```cpp
AMyActor() {
bAlwaysRelevant = true; // Replicate to all clients (e.g., GameState, PlayerController)
bOnlyRelevantToOwner = true; // Only replicate to owner (e.g., PlayerController)
}
```
---
## Ownership
### Set Owner
```cpp
// Assign owner (important for RPCs and relevancy)
MyActor->SetOwner(OwningPlayerController);
```
### Check Owner
```cpp
if (GetOwner() == PlayerController) {
// This actor is owned by this player
}
```
---
## Game Mode & Game State
### Game Mode (Server Only)
```cpp
UCLASS()
class AMyGameMode : public AGameMode {
GENERATED_BODY()
public:
// Game mode only exists on server
// Use for server-side logic (spawning, scoring, rules)
};
```
### Game State (Replicated to All Clients)
```cpp
UCLASS()
class AMyGameState : public AGameState {
GENERATED_BODY()
public:
// ✅ Replicate game state to all clients
UPROPERTY(Replicated)
int32 RedTeamScore;
UPROPERTY(Replicated)
int32 BlueTeamScore;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, RedTeamScore);
DOREPLIFETIME(AMyGameState, BlueTeamScore);
}
};
```
---
## Player Controller & Player State
### Player Controller (One per Player)
```cpp
UCLASS()
class AMyPlayerController : public APlayerController {
GENERATED_BODY()
public:
// Exists on server and owning client
// Use for player-specific logic, input handling
};
```
### Player State (Replicated Player Info)
```cpp
UCLASS()
class AMyPlayerState : public APlayerState {
GENERATED_BODY()
public:
UPROPERTY(Replicated)
int32 Kills;
UPROPERTY(Replicated)
int32 Deaths;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyPlayerState, Kills);
DOREPLIFETIME(AMyPlayerState, Deaths);
}
};
```
---
## Sessions & Matchmaking
### Create Session
```cpp
#include "OnlineSubsystem.h"
#include "OnlineSessionSettings.h"
void CreateSession() {
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings());
SessionSettings->bIsLANMatch = false;
SessionSettings->NumPublicConnections = 4;
SessionSettings->bShouldAdvertise = true;
Sessions->CreateSession(0, FName("MySession"), *SessionSettings);
}
```
### Find Sessions
```cpp
void FindSessions() {
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
TSharedRef<FOnlineSessionSearch> SearchSettings = MakeShareable(new FOnlineSessionSearch());
SearchSettings->bIsLanQuery = false;
SearchSettings->MaxSearchResults = 20;
Sessions->FindSessions(0, SearchSettings);
}
```
---
## Performance Tips
### Reduce Bandwidth
```cpp
// Use unreliable RPCs for frequent updates
UFUNCTION(Server, Unreliable)
void Server_UpdatePosition(FVector Pos);
// Conditional replication (only replicate to relevant clients)
DOREPLIFETIME_CONDITION(AMyActor, Health, COND_OwnerOnly);
// Limit replication frequency
SetReplicationFrequency(10.0f); // Update 10 times per second (default 100)
```
---
## Debugging
### Network Debugging
```cpp
// Console commands:
// stat net - Show network stats
// stat netplayerupdate - Show player update stats
// NetEmulation PktLoss=10 - Simulate 10% packet loss
// NetEmulation PktLag=100 - Simulate 100ms latency
// Draw debug for replication:
UE_LOG(LogNet, Warning, TEXT("Replicating Health: %d"), Health);
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/networking-and-multiplayer-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/actor-replication-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/rpcs-in-unreal-engine/

View File

@@ -0,0 +1,283 @@
# Unreal Engine 5.7 — Physics Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 Chaos Physics improvements
---
## Overview
UE 5 uses **Chaos Physics** (replaced PhysX in UE 4):
- Better performance
- Destruction support
- Vehicle physics improvements
---
## Rigid Body Physics
### Enable Physics on Static Mesh
```cpp
UStaticMeshComponent* MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
MeshComp->SetSimulatePhysics(true);
MeshComp->SetEnableGravity(true);
MeshComp->SetMassOverrideInKg(NAME_None, 50.0f); // 50 kg
```
### Apply Forces
```cpp
// Apply impulse (instant velocity change)
MeshComp->AddImpulse(FVector(0, 0, 1000), NAME_None, true);
// Apply force (continuous)
MeshComp->AddForce(FVector(0, 0, 500));
// Apply torque (rotation)
MeshComp->AddTorqueInRadians(FVector(0, 0, 100));
```
---
## Collision
### Collision Channels
```cpp
// Project Settings > Engine > Collision
// Define custom collision channels and responses
// Set collision in C++
MeshComp->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
MeshComp->SetCollisionObjectType(ECollisionChannel::ECC_Pawn);
MeshComp->SetCollisionResponseToAllChannels(ECR_Block);
MeshComp->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
```
### Collision Events
```cpp
// Enable collision events
MeshComp->SetNotifyRigidBodyCollision(true);
// Bind to OnComponentHit
MeshComp->OnComponentHit.AddDynamic(this, &AMyActor::OnHit);
UFUNCTION()
void AMyActor::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
UE_LOG(LogTemp, Warning, TEXT("Hit %s"), *OtherActor->GetName());
}
```
### Overlap Events
```cpp
// Enable overlap events
MeshComp->SetGenerateOverlapEvents(true);
// Bind to OnComponentBeginOverlap
MeshComp->OnComponentBeginOverlap.AddDynamic(this, &AMyActor::OnOverlapBegin);
UFUNCTION()
void AMyActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
UE_LOG(LogTemp, Warning, TEXT("Overlapped %s"), *OtherActor->GetName());
}
```
---
## Raycasting (Line Traces)
### Single Line Trace
```cpp
FHitResult HitResult;
FVector Start = GetActorLocation();
FVector End = Start + GetActorForwardVector() * 1000.0f;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(this);
// Perform trace
bool bHit = GetWorld()->LineTraceSingleByChannel(
HitResult,
Start,
End,
ECC_Visibility,
QueryParams
);
if (bHit) {
UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *HitResult.GetActor()->GetName());
DrawDebugLine(GetWorld(), Start, HitResult.Location, FColor::Red, false, 2.0f);
}
```
### Multi Line Trace
```cpp
TArray<FHitResult> HitResults;
bool bHit = GetWorld()->LineTraceMultiByChannel(
HitResults,
Start,
End,
ECC_Visibility,
QueryParams
);
for (const FHitResult& Hit : HitResults) {
UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *Hit.GetActor()->GetName());
}
```
### Sweep (Thick Trace)
```cpp
FHitResult HitResult;
FCollisionShape Sphere = FCollisionShape::MakeSphere(50.0f);
bool bHit = GetWorld()->SweepSingleByChannel(
HitResult,
Start,
End,
FQuat::Identity,
ECC_Visibility,
Sphere,
QueryParams
);
```
---
## Character Movement
### Character Movement Component
```cpp
// Built into ACharacter class
UCharacterMovementComponent* MoveComp = GetCharacterMovement();
// Configure movement
MoveComp->MaxWalkSpeed = 600.0f;
MoveComp->JumpZVelocity = 600.0f;
MoveComp->AirControl = 0.2f;
MoveComp->GravityScale = 1.0f;
MoveComp->bOrientRotationToMovement = true;
```
### Add Movement Input
```cpp
// In Character class
void AMyCharacter::MoveForward(float Value) {
if (Value != 0.0f) {
AddMovementInput(GetActorForwardVector(), Value);
}
}
void AMyCharacter::MoveRight(float Value) {
if (Value != 0.0f) {
AddMovementInput(GetActorRightVector(), Value);
}
}
```
---
## Physical Materials
### Create Physical Material
1. Content Browser > Right Click > Physics > Physical Material
2. Configure properties:
- Friction: 0.0 - 1.0
- Restitution (bounciness): 0.0 - 1.0
### Assign Physical Material
```cpp
// In static mesh editor: Physics > Phys Material Override
// Or in C++:
MeshComp->SetPhysMaterialOverride(PhysicalMaterial);
```
---
## Constraints (Physics Joints)
### Physics Constraint Component
```cpp
UPhysicsConstraintComponent* Constraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("Constraint"));
Constraint->SetConstrainedComponents(ComponentA, NAME_None, ComponentB, NAME_None);
// Configure constraint
Constraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Limited, 100.0f);
Constraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0.0f);
Constraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Free, 0.0f);
Constraint->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Limited, 45.0f);
```
---
## Destruction (Chaos Destruction)
### Enable Chaos Destruction
```cpp
// Plugin: Enable "Chaos" plugin
// Create Geometry Collection asset for destructible objects
```
### Destroy Geometry Collection
```cpp
// Fracture mesh in Chaos editor
// In game, apply damage:
UGeometryCollectionComponent* GeoComp = /* Get component */;
GeoComp->ApplyPhysicsField(/* Field parameters */);
```
---
## Performance Tips
### Physics Optimization
```cpp
// Simplify collision shapes (use simple primitives)
MeshComp->SetCollisionEnabled(ECollisionEnabled::NoCollision); // Disable when not needed
// Use Physics Asset for skeletal meshes (simplified collision)
// Don't simulate physics for distant objects
// Reduce physics substeps:
// Project Settings > Engine > Physics > Max Substep Delta Time
```
---
## Debugging
### Physics Debug Visualization
```cpp
// Console commands:
// show collision - Show collision shapes
// p.Chaos.DebugDraw.Enabled 1 - Show Chaos debug
// pxvis collision - Visualize collision
// Draw debug shapes:
DrawDebugSphere(GetWorld(), Location, Radius, 12, FColor::Green, false, 2.0f);
DrawDebugBox(GetWorld(), Location, Extent, FColor::Red, false, 2.0f);
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/physics-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/chaos-physics-overview-in-unreal-engine/

View File

@@ -0,0 +1,297 @@
# Unreal Engine 5.7 — Rendering Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 has Megalights, production-ready Substrate, and Lumen improvements
---
## Overview
UE 5.7 rendering stack:
- **Lumen**: Real-time global illumination (default)
- **Nanite**: Virtualized geometry for millions of triangles
- **Megalights**: Support for millions of dynamic lights (NEW in 5.5+)
- **Substrate**: Production-ready modular material system (NEW in 5.7)
---
## Lumen (Global Illumination)
### Enable Lumen
```cpp
// Project Settings > Engine > Rendering > Dynamic Global Illumination Method = Lumen
// Real-time GI, no lightmap baking needed
```
### Lumen Quality Settings
```ini
; DefaultEngine.ini
[/Script/Engine.RendererSettings]
r.Lumen.DiffuseColorBoost=1.0
r.Lumen.ScreenProbeGather.RadianceCache.NumFramesToKeepCached=2
```
### Lumen in C++
```cpp
// Check if Lumen is enabled
bool bIsLumenEnabled = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DynamicGlobalIlluminationMethod"))->GetInt() == 1;
```
---
## Nanite (Virtualized Geometry)
### Enable Nanite on Static Mesh
1. Static Mesh Editor
2. Details > Nanite Settings > Enable Nanite Support
3. Save mesh (auto-builds Nanite data)
### Nanite in C++
```cpp
// Spawn Nanite mesh
UStaticMeshComponent* MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
MeshComp->SetStaticMesh(NaniteMesh); // Automatically uses Nanite if enabled
```
### Nanite Limitations
- No vertex animation (skeletal meshes)
- No world position offset (WPO) in materials
- Best for static, high-poly geometry
---
## Megalights (UE 5.5+)
### Enable Megalights
```cpp
// Project Settings > Engine > Rendering > Megalights = Enabled
// Supports millions of dynamic lights with minimal performance cost
```
### Megalights Usage
```cpp
// Add point lights as usual
UPointLightComponent* Light = CreateDefaultSubobject<UPointLightComponent>(TEXT("Light"));
Light->SetIntensity(5000.0f);
Light->SetAttenuationRadius(500.0f);
// Megalights automatically handles thousands/millions of these
```
---
## Substrate Materials (Production-Ready in 5.7)
### Enable Substrate
```cpp
// Project Settings > Engine > Substrate > Enable Substrate
// Restart editor
```
### Substrate Material Nodes
- **Substrate Slab**: Physical material layer (diffuse, specular, etc.)
- **Substrate Blend**: Blend multiple layers
- **Substrate Thin Film**: Iridescence, soap bubbles
- **Substrate Hair**: Hair-specific shading
### Example Substrate Material Graph
```
Substrate Slab (Diffuse)
└─ Base Color: Texture Sample
└─ Roughness: Constant (0.5)
└─ Metallic: Constant (0.0)
└─ Connect to Material Output
```
---
## Materials (C++ API)
### Dynamic Material Instances
```cpp
// Create dynamic material instance
UMaterialInstanceDynamic* DynMat = UMaterialInstanceDynamic::Create(BaseMaterial, this);
// Set parameters
DynMat->SetVectorParameterValue(TEXT("BaseColor"), FLinearColor::Red);
DynMat->SetScalarParameterValue(TEXT("Metallic"), 0.8f);
DynMat->SetTextureParameterValue(TEXT("DiffuseTexture"), MyTexture);
// Apply to mesh
MeshComp->SetMaterial(0, DynMat);
```
---
## Post-Processing
### Post-Process Volume
```cpp
// Add to level
APostProcessVolume* PPV = GetWorld()->SpawnActor<APostProcessVolume>();
PPV->bUnbound = true; // Affect entire world
// Configure settings
PPV->Settings.bOverride_MotionBlurAmount = true;
PPV->Settings.MotionBlurAmount = 0.5f;
PPV->Settings.bOverride_BloomIntensity = true;
PPV->Settings.BloomIntensity = 1.0f;
```
### Post-Process in C++
```cpp
// Access camera post-process settings
APlayerController* PC = GetWorld()->GetFirstPlayerController();
if (APlayerCameraManager* CamManager = PC->PlayerCameraManager) {
CamManager->PostProcessBlendWeight = 1.0f;
CamManager->PostProcessSettings.BloomIntensity = 2.0f;
}
```
---
## Lighting
### Directional Light (Sun)
```cpp
ADirectionalLight* Sun = GetWorld()->SpawnActor<ADirectionalLight>();
Sun->SetActorRotation(FRotator(-45.f, 0.f, 0.f));
Sun->GetLightComponent()->SetIntensity(10.0f);
Sun->GetLightComponent()->bCastShadows = true;
```
### Point Light
```cpp
APointLight* Light = GetWorld()->SpawnActor<APointLight>();
Light->SetActorLocation(FVector(0, 0, 200));
Light->GetPointLightComponent()->SetIntensity(5000.0f);
Light->GetPointLightComponent()->SetAttenuationRadius(1000.0f);
Light->GetPointLightComponent()->SetLightColor(FLinearColor::Red);
```
### Spot Light
```cpp
ASpotLight* Spotlight = GetWorld()->SpawnActor<ASpotLight>();
Spotlight->GetSpotLightComponent()->SetInnerConeAngle(20.0f);
Spotlight->GetSpotLightComponent()->SetOuterConeAngle(40.0f);
```
---
## Render Targets (Render to Texture)
### Create Render Target
```cpp
// Create render target asset (2D texture)
UTextureRenderTarget2D* RenderTarget = NewObject<UTextureRenderTarget2D>();
RenderTarget->InitAutoFormat(512, 512); // 512x512 resolution
RenderTarget->UpdateResourceImmediate();
// Render scene to texture
UKismetRenderingLibrary::DrawMaterialToRenderTarget(
GetWorld(),
RenderTarget,
MaterialToDraw
);
```
---
## Custom Render Passes (Advanced)
### Render Dependency Graph (RDG)
```cpp
// UE5 uses Render Dependency Graph for custom rendering
// Example: Custom post-process pass
#include "RenderGraphBuilder.h"
void RenderCustomPass(FRDGBuilder& GraphBuilder, const FViewInfo& View) {
FRDGTextureRef SceneColor = /* Get scene color texture */;
// Define pass parameters
struct FPassParameters {
FRDGTextureRef InputTexture;
};
FPassParameters* PassParams = GraphBuilder.AllocParameters<FPassParameters>();
PassParams->InputTexture = SceneColor;
// Add render pass
GraphBuilder.AddPass(
RDG_EVENT_NAME("CustomPass"),
PassParams,
ERDGPassFlags::Raster,
[](FRHICommandList& RHICmdList, const FPassParameters* Params) {
// Render commands
}
);
}
```
---
## Performance
### Render Stats
```cpp
// Console commands for profiling:
// stat fps - Show FPS
// stat unit - Show frame time breakdown
// stat gpu - Show GPU timings
// profilegpu - Detailed GPU profile
```
### Scalability Settings
```cpp
// Get current scalability settings
UGameUserSettings* Settings = UGameUserSettings::GetGameUserSettings();
int32 ViewDistanceQuality = Settings->GetViewDistanceQuality(); // 0-4
// Set scalability
Settings->SetViewDistanceQuality(3); // High
Settings->SetShadowQuality(2); // Medium
Settings->ApplySettings(false);
```
---
## Debugging
### Visualize Render Features
```
Console commands:
- r.Lumen.Visualize 1 - Show Lumen debug
- r.Nanite.Visualize 1 - Show Nanite triangles
- viewmode wireframe - Wireframe mode
- viewmode unlit - Disable lighting
- show collision - Show collision meshes
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/lumen-global-illumination-and-reflections-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/nanite-virtualized-geometry-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/substrate-materials-in-unreal-engine/

View File

@@ -0,0 +1,353 @@
# Unreal Engine 5.7 — UI Module Reference
**Last verified:** 2026-02-13
**Knowledge Gap:** UE 5.7 UMG and CommonUI improvements
---
## Overview
UE 5.7 UI systems:
- **UMG (Unreal Motion Graphics)**: Visual widget-based UI (RECOMMENDED)
- **CommonUI**: Cross-platform input-aware UI framework (console/PC)
- **Slate**: Low-level C++ UI (engine/editor UI)
---
## UMG (Unreal Motion Graphics)
### Create Widget Blueprint
1. Content Browser > User Interface > Widget Blueprint
2. Open Widget Designer
3. Drag widgets from Palette: Button, Text, Image, ProgressBar, etc.
---
## Basic UMG Setup in C++
### Create and Display Widget
```cpp
#include "Blueprint/UserWidget.h"
UPROPERTY(EditAnywhere, Category = "UI")
TSubclassOf<UUserWidget> HealthBarWidgetClass;
void AMyCharacter::BeginPlay() {
Super::BeginPlay();
// Create widget
UUserWidget* HealthBarWidget = CreateWidget<UUserWidget>(GetWorld(), HealthBarWidgetClass);
// Add to viewport
HealthBarWidget->AddToViewport();
}
```
### Remove Widget
```cpp
HealthBarWidget->RemoveFromParent();
```
---
## Access Widget Elements from C++
### Bind to Widget Elements
```cpp
UCLASS()
class UMyHealthWidget : public UUserWidget {
GENERATED_BODY()
public:
// ✅ Bind to widget elements (must match names in Widget Blueprint)
UPROPERTY(meta = (BindWidget))
TObjectPtr<UTextBlock> HealthText;
UPROPERTY(meta = (BindWidget))
TObjectPtr<UProgressBar> HealthBar;
void UpdateHealth(int32 CurrentHealth, int32 MaxHealth) {
HealthText->SetText(FText::FromString(FString::Printf(TEXT("%d / %d"), CurrentHealth, MaxHealth)));
HealthBar->SetPercent((float)CurrentHealth / MaxHealth);
}
};
```
---
## Common UMG Widgets
### Text Block
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UTextBlock> ScoreText;
ScoreText->SetText(FText::FromString(TEXT("Score: 100")));
ScoreText->SetColorAndOpacity(FLinearColor::Green);
```
### Button
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UButton> PlayButton;
void NativeConstruct() override {
Super::NativeConstruct();
// Bind button click
PlayButton->OnClicked.AddDynamic(this, &UMyMenuWidget::OnPlayClicked);
}
UFUNCTION()
void OnPlayClicked() {
UE_LOG(LogTemp, Warning, TEXT("Play clicked"));
}
```
### Image
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UImage> PlayerAvatar;
PlayerAvatar->SetBrushFromTexture(AvatarTexture);
PlayerAvatar->SetColorAndOpacity(FLinearColor::White);
```
### Progress Bar
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UProgressBar> HealthBar;
HealthBar->SetPercent(0.75f); // 75%
HealthBar->SetFillColorAndOpacity(FLinearColor::Red);
```
### Slider
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<USlider> VolumeSlider;
void NativeConstruct() override {
Super::NativeConstruct();
VolumeSlider->OnValueChanged.AddDynamic(this, &UMyWidget::OnVolumeChanged);
}
UFUNCTION()
void OnVolumeChanged(float Value) {
// Value is 0.0 - 1.0
UE_LOG(LogTemp, Warning, TEXT("Volume: %f"), Value);
}
```
### EditableTextBox (Input Field)
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UEditableTextBox> PlayerNameInput;
void NativeConstruct() override {
Super::NativeConstruct();
PlayerNameInput->OnTextChanged.AddDynamic(this, &UMyWidget::OnNameChanged);
}
UFUNCTION()
void OnNameChanged(const FText& Text) {
FString PlayerName = Text.ToString();
}
```
---
## UMG Animations
### Play Animation
```cpp
UPROPERTY(Transient, meta = (BindWidgetAnim))
TObjectPtr<UWidgetAnimation> FadeInAnimation;
void ShowUI() {
PlayAnimation(FadeInAnimation);
}
```
### Stop Animation
```cpp
StopAnimation(FadeInAnimation);
```
---
## Canvas Panel (Layout)
### Canvas Panel (Absolute Positioning)
```cpp
// Use in Widget Blueprint for absolute positioning
// Anchor widgets to corners/edges for responsive UI
```
### Vertical Box (Stack Vertically)
```cpp
// Auto-stacks children vertically
```
### Horizontal Box (Stack Horizontally)
```cpp
// Auto-stacks children horizontally
```
### Grid Panel (Grid Layout)
```cpp
// Arranges children in a grid
```
---
## World Space UI (3D UI)
### Widget Component (3D UI in World)
```cpp
#include "Components/WidgetComponent.h"
UWidgetComponent* HealthBarWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("HealthBar"));
HealthBarWidget->SetupAttachment(RootComponent);
HealthBarWidget->SetWidgetClass(HealthBarWidgetClass);
HealthBarWidget->SetWidgetSpace(EWidgetSpace::World); // 3D world space
HealthBarWidget->SetDrawSize(FVector2D(200, 50));
```
---
## Input Handling in UMG
### Override Keyboard Input
```cpp
UCLASS()
class UMyWidget : public UUserWidget {
GENERATED_BODY()
public:
virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override {
if (InKeyEvent.GetKey() == EKeys::Escape) {
// Handle Escape key
CloseMenu();
return FReply::Handled();
}
return Super::NativeOnKeyDown(InGeometry, InKeyEvent);
}
};
```
---
## CommonUI (Cross-Platform Input)
### Enable CommonUI Plugin
```cpp
// Enable: Edit > Plugins > CommonUI
// Restart editor
```
### Use CommonUI Widgets
```cpp
// CommonUI widgets:
// - CommonActivatableWidget: Base for screens/menus
// - CommonButtonBase: Input-aware button (gamepad + mouse)
// - CommonTextBlock: Text with styling
```
### CommonActivatableWidget Example
```cpp
UCLASS()
class UMyMenuWidget : public UCommonActivatableWidget {
GENERATED_BODY()
public:
virtual void NativeOnActivated() override {
Super::NativeOnActivated();
// Menu activated (shown)
}
virtual void NativeOnDeactivated() override {
Super::NativeOnDeactivated();
// Menu deactivated (hidden)
}
};
```
---
## HUD Class (Alternative to UMG)
### Create HUD
```cpp
UCLASS()
class AMyHUD : public AHUD {
GENERATED_BODY()
public:
virtual void DrawHUD() override {
Super::DrawHUD();
// Draw text
DrawText(TEXT("Score: 100"), FLinearColor::White, 50, 50);
// Draw texture
DrawTexture(CrosshairTexture, Canvas->SizeX / 2, Canvas->SizeY / 2, 32, 32);
}
};
```
---
## Performance Tips
### Optimize UMG
```cpp
// Invalidation boxes: Only redraw when content changes
// Add "Invalidation Box" widget to Widget Blueprint
// Disable tick if not needed
bIsFocusable = false;
SetVisibility(ESlateVisibility::Collapsed); // Collapsed = not rendered
```
---
## Debugging
### UI Debug Commands
```cpp
// Console commands:
// widget.debug - Show widget hierarchy
// Slate.ShowDebugOutlines 1 - Show widget bounds
// stat slate - Show Slate performance
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/umg-ui-designer-for-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/commonui-plugin-for-advanced-user-interfaces-in-unreal-engine/

View File

@@ -0,0 +1,389 @@
# Unreal Engine 5.7 — CommonUI Plugin
**Last verified:** 2026-02-13
**Status:** Production-Ready
**Plugin:** `CommonUI` (built-in, enable in Plugins)
---
## Overview
**CommonUI** is a cross-platform UI framework that automatically handles input routing
for gamepad, mouse, and touch. It's designed for games that need to work seamlessly
across PC, console, and mobile platforms with minimal platform-specific code.
**Use CommonUI for:**
- Multi-platform games (console + PC)
- Automatic gamepad/mouse/touch input routing
- Input-agnostic UI (same UI works with any input method)
- Widget focus and navigation
- Action bars and input hints
**DON'T use CommonUI for:**
- PC-only games with mouse-only UI (standard UMG is simpler)
- Simple UI with no navigation requirements
---
## Key Differences from Standard UMG
| Feature | Standard UMG | CommonUI |
|---------|--------------|----------|
| **Input Handling** | Manual per widget | Automatic routing |
| **Focus Management** | Basic | Advanced navigation |
| **Platform Switching** | Manual detection | Automatic |
| **Input Prompts** | Hardcode icons | Dynamic per platform |
| **Screen Stack** | Manual | Built-in activatable widgets |
---
## Setup
### 1. Enable Plugin
`Edit > Plugins > CommonUI > Enabled > Restart`
### 2. Configure Project Settings
`Project Settings > Plugins > CommonUI`:
- **Default Input Type**: Gamepad (or auto-detect)
- **Platform-Specific Settings**: Configure input icons per platform
### 3. Create Common Input Settings Asset
1. Content Browser > Input > Common Input Settings
2. Configure input data per platform:
- Default Gamepad Data
- Default Mouse & Keyboard Data
- Default Touch Data
---
## Core Widgets
### CommonActivatableWidget (Screen Management)
Base class for screens/menus that can be activated/deactivated.
```cpp
#include "CommonActivatableWidget.h"
UCLASS()
class UMyMenuWidget : public UCommonActivatableWidget {
GENERATED_BODY()
protected:
virtual void NativeOnActivated() override {
Super::NativeOnActivated();
// Menu is now visible and focused
UE_LOG(LogTemp, Warning, TEXT("Menu activated"));
}
virtual void NativeOnDeactivated() override {
Super::NativeOnDeactivated();
// Menu is now hidden
UE_LOG(LogTemp, Warning, TEXT("Menu deactivated"));
}
virtual UWidget* NativeGetDesiredFocusTarget() const override {
// Return widget that should receive focus (e.g., first button)
return PlayButton;
}
private:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonButtonBase> PlayButton;
};
```
---
### CommonButtonBase (Input-Aware Button)
Replaces standard UMG Button. Automatically handles gamepad/mouse/keyboard input.
```cpp
#include "CommonButtonBase.h"
UCLASS()
class UMyMenuWidget : public UCommonActivatableWidget {
GENERATED_BODY()
protected:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonButtonBase> PlayButton;
virtual void NativeConstruct() override {
Super::NativeConstruct();
// Bind button click (works with any input method)
PlayButton->OnClicked().AddUObject(this, &UMyMenuWidget::OnPlayClicked);
// Set button text
PlayButton->SetButtonText(FText::FromString(TEXT("Play")));
}
void OnPlayClicked() {
UE_LOG(LogTemp, Warning, TEXT("Play clicked"));
}
};
```
---
### CommonTextBlock (Styled Text)
Text widget with CommonUI styling support.
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonTextBlock> TitleText;
TitleText->SetText(FText::FromString(TEXT("Main Menu")));
```
---
### CommonActionWidget (Input Prompts)
Displays input prompts (e.g., "Press A to Continue", automatically shows correct button icon).
```cpp
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonActionWidget> ConfirmActionWidget;
// Bind to input action
ConfirmActionWidget->SetInputAction(ConfirmInputActionData);
// Automatically shows correct icon (A on Xbox, X on PlayStation, Enter on PC)
```
---
## Widget Stack (Screen Management)
### CommonActivatableWidgetStack
Manages a stack of screens (e.g., Main Menu → Settings → Controls).
```cpp
#include "Widgets/CommonActivatableWidgetContainer.h"
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonActivatableWidgetStack> WidgetStack;
// Push new screen onto stack
void ShowSettingsMenu() {
WidgetStack->AddWidget(USettingsMenuWidget::StaticClass());
}
// Pop current screen (go back)
void GoBack() {
WidgetStack->DeactivateWidget();
}
```
---
## Input Actions (CommonUI Style)
### Define Input Actions
Create **Common Input Action Data Table**:
1. Content Browser > Miscellaneous > Data Table
2. Row Structure: `CommonInputActionDataBase`
3. Add rows for actions (Confirm, Cancel, Navigate, etc.)
Example row:
- **Action Name**: Confirm
- **Default Input**: Gamepad Face Button Bottom (A/Cross)
- **Alternate Inputs**: Enter (keyboard), Left Mouse Button
---
### Bind Input Actions in Widget
```cpp
#include "Input/CommonUIActionRouterBase.h"
UCLASS()
class UMyWidget : public UCommonActivatableWidget {
GENERATED_BODY()
protected:
virtual void NativeOnActivated() override {
Super::NativeOnActivated();
// Bind input action
FBindUIActionArgs BindArgs(ConfirmInputAction, FSimpleDelegate::CreateUObject(this, &UMyWidget::OnConfirm));
BindArgs.bDisplayInActionBar = true; // Show in action bar
RegisterUIActionBinding(BindArgs);
}
void OnConfirm() {
UE_LOG(LogTemp, Warning, TEXT("Confirmed"));
}
private:
UPROPERTY(EditDefaultsOnly, Category = "Input")
FDataTableRowHandle ConfirmInputAction;
};
```
---
## Focus & Navigation
### Automatic Gamepad Navigation
CommonUI automatically handles gamepad navigation (D-Pad/Stick to move between buttons).
```cpp
// In Widget Blueprint:
// - Widgets are automatically navigable if they inherit from CommonButton/CommonUserWidget
// - Focus order is determined by widget hierarchy and layout
```
### Custom Focus Navigation
```cpp
// Override focus navigation
virtual UWidget* NativeGetDesiredFocusTarget() const override {
return FirstButton; // Return widget that should receive focus
}
```
---
## Input Mode (Game vs UI)
### Switch Input Mode
```cpp
#include "CommonUIExtensions.h"
// Switch to UI-only mode (pause game, show cursor)
UCommonUIExtensions::PushStreamedGameplayUIInputConfig(this, FrontendInputConfig);
// Return to game mode (hide cursor, resume gameplay)
UCommonUIExtensions::PopInputConfig(this);
```
---
## Platform-Specific Input Icons
### Configure Input Icons
1. Create **Common Input Base Controller Data** asset for each platform:
- Gamepad (Xbox, PlayStation, Switch)
- Mouse & Keyboard
- Touch
2. Assign platform-specific icons:
- Gamepad Face Button Bottom: `A` (Xbox), `Cross` (PlayStation)
- Confirm Key: `Enter` icon
3. Assign to **Common Input Settings** asset
### Automatically Display Correct Icons
```cpp
// CommonActionWidget automatically shows correct icon for current platform
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonActionWidget> JumpActionWidget;
JumpActionWidget->SetInputAction(JumpInputActionData);
// Shows "A" on Xbox, "Cross" on PlayStation, "Space" on PC
```
---
## Common Patterns
### Main Menu with Navigation
```cpp
UCLASS()
class UMainMenuWidget : public UCommonActivatableWidget {
GENERATED_BODY()
protected:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonButtonBase> PlayButton;
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonButtonBase> SettingsButton;
UPROPERTY(meta = (BindWidget))
TObjectPtr<UCommonButtonBase> QuitButton;
virtual void NativeConstruct() override {
Super::NativeConstruct();
PlayButton->OnClicked().AddUObject(this, &UMainMenuWidget::OnPlayClicked);
SettingsButton->OnClicked().AddUObject(this, &UMainMenuWidget::OnSettingsClicked);
QuitButton->OnClicked().AddUObject(this, &UMainMenuWidget::OnQuitClicked);
}
virtual UWidget* NativeGetDesiredFocusTarget() const override {
return PlayButton; // Focus "Play" button when menu opens
}
void OnPlayClicked() { /* Start game */ }
void OnSettingsClicked() { /* Open settings */ }
void OnQuitClicked() { /* Quit game */ }
};
```
---
### Pause Menu with Back Action
```cpp
UCLASS()
class UPauseMenuWidget : public UCommonActivatableWidget {
GENERATED_BODY()
protected:
UPROPERTY(EditDefaultsOnly, Category = "Input")
FDataTableRowHandle BackInputAction; // Assign "Cancel" action in Blueprint
virtual void NativeOnActivated() override {
Super::NativeOnActivated();
// Bind "Back" input (B/Circle/Escape)
FBindUIActionArgs BindArgs(BackInputAction, FSimpleDelegate::CreateUObject(this, &UPauseMenuWidget::OnBack));
RegisterUIActionBinding(BindArgs);
}
void OnBack() {
DeactivateWidget(); // Close pause menu
}
};
```
---
## Performance Tips
- Use **CommonActivatableWidgetStack** for screen management (automatically handles activation/deactivation)
- Avoid creating/destroying widgets every frame (reuse widgets)
- Use **Lazy Widgets** for complex menus (only create when needed)
---
## Debugging
### CommonUI Debug Commands
```cpp
// Console commands:
// CommonUI.DumpActivatableTree - Show active widget hierarchy
// CommonUI.DumpActionBindings - Show registered input actions
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/commonui-plugin-for-advanced-user-interfaces-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/commonui-quickstart-guide-for-unreal-engine/

View File

@@ -0,0 +1,386 @@
# Unreal Engine 5.7 — Gameplay Ability System (GAS)
**Last verified:** 2026-02-13
**Status:** Production-Ready
**Plugin:** `GameplayAbilities` (built-in, enable in Plugins)
---
## Overview
**Gameplay Ability System (GAS)** is a modular framework for building abilities, attributes,
effects, and gameplay mechanics. It's the standard for RPGs, MOBAs, shooters with abilities,
and any game with complex ability systems.
**Use GAS for:**
- Character abilities (spells, skills, attacks)
- Attributes (health, mana, stamina, stats)
- Buffs/debuffs (temporary effects)
- Cooldowns and costs
- Damage calculation
- Multiplayer-ready ability replication
---
## Core Concepts
### 1. **Ability System Component** (ASC)
- The main component that owns abilities, attributes, and effects
- Added to Characters or PlayerStates
### 2. **Gameplay Abilities**
- Individual skills/actions (fireball, heal, dash, etc.)
- Activated, committed (cost/cooldown), and can be cancelled
### 3. **Attributes & Attribute Sets**
- Stats that can be modified (Health, Mana, Stamina, Strength, etc.)
- Stored in Attribute Sets
### 4. **Gameplay Effects**
- Modify attributes (damage, healing, buffs, debuffs)
- Can be instant, duration-based, or infinite
### 5. **Gameplay Tags**
- Hierarchical tags for ability logic (e.g., `Ability.Attack.Melee`, `Status.Stunned`)
---
## Setup
### 1. Enable Plugin
`Edit > Plugins > Gameplay Abilities > Enabled > Restart`
### 2. Add Ability System Component
```cpp
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
UCLASS()
class AMyCharacter : public ACharacter {
GENERATED_BODY()
public:
AMyCharacter() {
// Create ASC
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
// Create Attribute Set
AttributeSet = CreateDefaultSubobject<UMyAttributeSet>(TEXT("AttributeSet"));
}
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Abilities")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY()
TObjectPtr<const UAttributeSet> AttributeSet;
};
```
### 3. Initialize ASC (Important for Multiplayer)
```cpp
void AMyCharacter::PossessedBy(AController* NewController) {
Super::PossessedBy(NewController);
// Server: Initialize ASC
if (AbilitySystemComponent) {
AbilitySystemComponent->InitAbilityActorInfo(this, this);
GiveDefaultAbilities();
}
}
void AMyCharacter::OnRep_PlayerState() {
Super::OnRep_PlayerState();
// Client: Initialize ASC
if (AbilitySystemComponent) {
AbilitySystemComponent->InitAbilityActorInfo(this, this);
}
}
```
---
## Attributes & Attribute Sets
### Create Attribute Set
```cpp
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
UCLASS()
class UMyAttributeSet : public UAttributeSet {
GENERATED_BODY()
public:
UMyAttributeSet();
// Health
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Health)
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, MaxHealth)
// Mana
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_Mana)
FGameplayAttributeData Mana;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Mana)
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
UFUNCTION()
virtual void OnRep_Health(const FGameplayAttributeData& OldHealth);
UFUNCTION()
virtual void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth);
UFUNCTION()
virtual void OnRep_Mana(const FGameplayAttributeData& OldMana);
};
```
### Implement Attribute Set
```cpp
#include "Net/UnrealNetwork.h"
UMyAttributeSet::UMyAttributeSet() {
// Default values
Health = 100.0f;
MaxHealth = 100.0f;
Mana = 50.0f;
}
void UMyAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, Health, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, Mana, COND_None, REPNOTIFY_Always);
}
void UMyAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) {
GAMEPLAYATTRIBUTE_REPNOTIFY(UMyAttributeSet, Health, OldHealth);
}
// Implement other OnRep functions similarly...
```
---
## Gameplay Abilities
### Create Gameplay Ability
```cpp
#include "Abilities/GameplayAbility.h"
UCLASS()
class UGA_Fireball : public UGameplayAbility {
GENERATED_BODY()
public:
UGA_Fireball() {
// Ability config
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::ServerInitiated;
// Tags
AbilityTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Fireball")));
}
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override {
if (!CommitAbility(Handle, ActorInfo, ActivationInfo)) {
// Failed to commit (not enough mana, on cooldown, etc.)
EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
return;
}
// Spawn fireball projectile
SpawnFireball();
// End ability
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
}
void SpawnFireball() {
// Spawn fireball logic
}
};
```
### Grant Abilities to Character
```cpp
void AMyCharacter::GiveDefaultAbilities() {
if (!HasAuthority() || !AbilitySystemComponent) return;
// Grant abilities
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(UGA_Fireball::StaticClass(), 1, INDEX_NONE, this));
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(UGA_Heal::StaticClass(), 1, INDEX_NONE, this));
}
```
### Activate Ability
```cpp
// Activate by class
AbilitySystemComponent->TryActivateAbilityByClass(UGA_Fireball::StaticClass());
// Activate by tag
FGameplayTagContainer TagContainer;
TagContainer.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Fireball")));
AbilitySystemComponent->TryActivateAbilitiesByTag(TagContainer);
```
---
## Gameplay Effects
### Create Gameplay Effect (Damage)
```cpp
// Create Blueprint: Content Browser > Gameplay > Gameplay Effect
// OR in C++:
UCLASS()
class UGE_Damage : public UGameplayEffect {
GENERATED_BODY()
public:
UGE_Damage() {
// Instant damage
DurationPolicy = EGameplayEffectDurationType::Instant;
// Modifier: Reduce Health
FGameplayModifierInfo ModifierInfo;
ModifierInfo.Attribute = UMyAttributeSet::GetHealthAttribute();
ModifierInfo.ModifierOp = EGameplayModOp::Additive;
ModifierInfo.ModifierMagnitude = FScalableFloat(-25.0f); // -25 health
Modifiers.Add(ModifierInfo);
}
};
```
### Apply Gameplay Effect
```cpp
// Apply damage to target
if (UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target)) {
FGameplayEffectContextHandle EffectContext = AbilitySystemComponent->MakeEffectContext();
EffectContext.AddSourceObject(this);
FGameplayEffectSpecHandle SpecHandle = AbilitySystemComponent->MakeOutgoingSpec(
UGE_Damage::StaticClass(), 1, EffectContext);
if (SpecHandle.IsValid()) {
AbilitySystemComponent->ApplyGameplayEffectSpecToTarget(*SpecHandle.Data.Get(), TargetASC);
}
}
```
---
## Gameplay Tags
### Define Tags
`Project Settings > Project > Gameplay Tags > Gameplay Tag List`
Example hierarchy:
```
Ability
├─ Ability.Attack
│ ├─ Ability.Attack.Melee
│ └─ Ability.Attack.Ranged
├─ Ability.Defend
└─ Ability.Utility
Status
├─ Status.Stunned
├─ Status.Invulnerable
└─ Status.Silenced
```
### Use Tags in Abilities
```cpp
UCLASS()
class UGA_MeleeAttack : public UGameplayAbility {
GENERATED_BODY()
public:
UGA_MeleeAttack() {
// This ability has these tags
AbilityTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Melee")));
// Block these tags while active
BlockAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack")));
// Cancel these abilities when activated
CancelAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Defend")));
// Can't activate if target has these tags
ActivationBlockedTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Status.Stunned")));
}
};
```
---
## Cooldowns & Costs
### Add Cooldown
```cpp
// In Ability Blueprint or C++:
// Create Gameplay Effect with Duration = Cooldown time
// Assign to Ability > Cooldown Gameplay Effect Class
```
### Add Cost (Mana)
```cpp
// Create Gameplay Effect that reduces Mana
// Assign to Ability > Cost Gameplay Effect Class
```
---
## Common Patterns
### Get Current Attribute Value
```cpp
float CurrentHealth = AbilitySystemComponent->GetNumericAttribute(UMyAttributeSet::GetHealthAttribute());
```
### Listen for Attribute Changes
```cpp
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(UMyAttributeSet::GetHealthAttribute())
.AddUObject(this, &AMyCharacter::OnHealthChanged);
void AMyCharacter::OnHealthChanged(const FOnAttributeChangeData& Data) {
UE_LOG(LogTemp, Warning, TEXT("Health: %f"), Data.NewValue);
}
```
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/gameplay-ability-system-for-unreal-engine/
- https://github.com/tranek/GASDocumentation (community guide)

View File

@@ -0,0 +1,321 @@
# Unreal Engine 5.7 — Gameplay Camera System
**Last verified:** 2026-02-13
**Status:** ⚠️ Experimental (introduced in UE 5.5)
**Plugin:** `GameplayCameras` (built-in, enable in Plugins)
---
## Overview
**Gameplay Camera System** is a modular camera management framework introduced in UE 5.5.
It replaces traditional camera setups with a flexible, node-based system that handles
camera modes, blending, and context-aware camera behavior.
**Use Gameplay Cameras for:**
- Dynamic camera behavior (3rd person, aiming, vehicles, cinematic)
- Context-aware camera switching (combat, exploration, dialogue)
- Smooth camera blending between modes
- Procedural camera motion (camera shake, lag, offset)
**⚠️ Warning:** This plugin is experimental in UE 5.5-5.7. Expect API changes in future versions.
---
## Core Concepts
### 1. **Camera Rig**
- Defines camera configuration (position, rotation, FOV, etc.)
- Modular node graph (similar to Material Editor)
### 2. **Camera Director**
- Manages which camera rig is active
- Handles blending between camera rigs
### 3. **Camera Nodes**
- Building blocks for camera behavior:
- **Position Nodes**: Orbit, Follow, Fixed Position
- **Rotation Nodes**: Look At, Match Actor Rotation
- **Modifiers**: Camera Shake, Lag, Offset
---
## Setup
### 1. Enable Plugin
`Edit > Plugins > Gameplay Cameras > Enabled > Restart`
### 2. Add Camera Component
```cpp
#include "GameplayCameras/Public/GameplayCameraComponent.h"
UCLASS()
class AMyCharacter : public ACharacter {
GENERATED_BODY()
public:
AMyCharacter() {
// Create camera component
CameraComponent = CreateDefaultSubobject<UGameplayCameraComponent>(TEXT("GameplayCamera"));
CameraComponent->SetupAttachment(RootComponent);
}
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
TObjectPtr<UGameplayCameraComponent> CameraComponent;
};
```
---
## Create Camera Rig
### 1. Create Camera Rig Asset
1. Content Browser > Gameplay > Gameplay Camera Rig
2. Open Camera Rig Editor (node-based graph)
### 2. Build Camera Rig (Example: Third Person)
**Node Setup:**
```
Actor Position (Character)
Orbit Node (Orbit around character)
Offset Node (Shoulder offset)
Look At Node (Look at character)
Camera Output
```
---
## Camera Nodes
### Position Nodes
#### Orbit Node (Third Person)
- Orbits around target actor
- Configure:
- **Orbit Distance**: Distance from target (e.g., 300 units)
- **Pitch Range**: Min/Max pitch angles
- **Yaw Range**: Min/Max yaw angles
#### Follow Node (Smooth Follow)
- Follows target with lag
- Configure:
- **Lag Speed**: How quickly camera catches up
- **Offset**: Fixed offset from target
#### Fixed Position Node
- Static camera position in world space
---
### Rotation Nodes
#### Look At Node
- Points camera at target
- Configure:
- **Target**: Actor or component to look at
- **Offset**: Look-at offset (e.g., aim at head instead of feet)
#### Match Actor Rotation
- Matches target actor's rotation
- Useful for first-person or vehicle cameras
---
### Modifier Nodes
#### Camera Shake
- Adds procedural shake (e.g., footsteps, explosions)
- Configure:
- **Shake Pattern**: Perlin noise, sine wave, custom
- **Amplitude**: Shake strength
#### Camera Lag
- Smooth dampening of camera movement
- Configure:
- **Lag Speed**: Damping factor (0 = instant, higher = more lag)
#### Offset Node
- Static offset from calculated position
- Useful for shoulder camera offset
---
## Camera Director (Switching Between Rigs)
### Assign Camera Rig
```cpp
#include "GameplayCameras/Public/GameplayCameraComponent.h"
void AMyCharacter::SetCameraMode(UGameplayCameraRig* NewRig) {
if (CameraComponent) {
CameraComponent->SetCameraRig(NewRig);
}
}
```
### Blend Between Camera Rigs
```cpp
// Blend to aiming camera over 0.5 seconds
CameraComponent->BlendToCameraRig(AimingCameraRig, 0.5f);
```
---
## Example: Third Person + Aiming
### 1. Create Two Camera Rigs
**Third Person Rig:**
```
Actor Position → Orbit (distance: 300) → Look At → Output
```
**Aiming Rig:**
```
Actor Position → Orbit (distance: 150) → Offset (shoulder) → Look At → Output
```
### 2. Switch on Aim
```cpp
UPROPERTY(EditAnywhere, Category = "Camera")
TObjectPtr<UGameplayCameraRig> ThirdPersonRig;
UPROPERTY(EditAnywhere, Category = "Camera")
TObjectPtr<UGameplayCameraRig> AimingRig;
void StartAiming() {
CameraComponent->BlendToCameraRig(AimingRig, 0.3f); // Blend over 0.3s
}
void StopAiming() {
CameraComponent->BlendToCameraRig(ThirdPersonRig, 0.3f);
}
```
---
## Common Patterns
### Over-the-Shoulder Camera
```
Actor Position
Orbit Node (distance: 250, yaw offset: 30°)
Offset Node (X: 0, Y: 50, Z: 50) // Shoulder offset
Look At Node (target: Character head)
Output
```
---
### Vehicle Camera
```
Vehicle Position
Follow Node (lag: 0.2)
Offset Node (behind vehicle: X: -400, Z: 150)
Look At Node (target: Vehicle)
Output
```
---
### First Person Camera
```
Character Head Socket
Match Actor Rotation
Output
```
---
## Camera Shake
### Trigger Camera Shake
```cpp
#include "GameplayCameras/Public/GameplayCameraShake.h"
void TriggerExplosionShake() {
if (APlayerController* PC = GetWorld()->GetFirstPlayerController()) {
if (UGameplayCameraComponent* CameraComp = PC->FindComponentByClass<UGameplayCameraComponent>()) {
CameraComp->PlayCameraShake(ExplosionShakeClass, 1.0f);
}
}
}
```
---
## Performance Tips
- Limit camera shake frequency (don't trigger every frame)
- Use camera lag sparingly (expensive for high lag values)
- Cache camera rig references (don't search every frame)
---
## Debugging
### Camera Debug Visualization
```cpp
// Console commands:
// GameplayCameras.Debug 1 - Show active camera rig info
// showdebug camera - Show camera debug info
```
---
## Migration from Legacy Cameras
### Old Spring Arm + Camera Component
```cpp
// ❌ OLD: Spring Arm Component
USpringArmComponent* SpringArm;
UCameraComponent* Camera;
// ✅ NEW: Gameplay Camera Component
UGameplayCameraComponent* CameraComponent;
// Build orbit + look-at rig in Camera Rig asset
```
---
## Limitations (Experimental Status)
- **API Instability**: Expect breaking changes in UE 5.8+
- **Limited Documentation**: Official docs still evolving
- **Blueprint Support**: Primarily C++ focused (Blueprint support improving)
- **Production Risk**: Test thoroughly before shipping
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/gameplay-cameras-in-unreal-engine/
- UE 5.5+ Release Notes
- **Note:** This system is experimental. Always check latest official docs for API changes.

View File

@@ -0,0 +1,356 @@
# Unreal Engine 5.7 — PCG (Procedural Content Generation)
**Last verified:** 2026-02-13
**Status:** Production-Ready (as of UE 5.7)
**Plugin:** `PCG` (built-in, enable in Plugins)
---
## Overview
**Procedural Content Generation (PCG)** is Unreal's node-based framework for generating
procedural content at massive scale. It's designed for populating large open worlds with
foliage, rocks, props, buildings, and other environmental detail.
**Use PCG for:**
- Procedural foliage placement (trees, grass, rocks)
- Biome-based environment generation
- Road/path generation
- Building/structure placement
- World detail population (props, clutter)
**DON'T use PCG for:**
- Gameplay logic (use Blueprints/C++)
- One-off manual placement (use editor tools)
**⚠️ Note:** PCG was experimental in UE 5.0-5.6, became production-ready in UE 5.7.
---
## Core Concepts
### 1. **PCG Graph**
- Node-based graph (similar to Material Editor)
- Defines generation rules
### 2. **PCG Component**
- Placed in level, executes PCG Graph
- Generates content in defined volume
### 3. **PCG Data**
- Point data (positions, rotations, scales)
- Spline data (paths, roads, rivers)
- Volume data (density, biome masks)
### 4. **Nodes**
- **Samplers**: Generate points (Grid, Poisson, Surface)
- **Filters**: Remove points based on rules (Density, Tag, Bounds)
- **Modifiers**: Transform points (Offset, Rotate, Scale)
- **Spawners**: Instantiate meshes/actors at points
---
## Setup
### 1. Enable Plugin
`Edit > Plugins > PCG > Enabled > Restart`
### 2. Create PCG Volume
1. Place Actors > Volumes > PCG Volume
2. Scale volume to desired generation area
### 3. Create PCG Graph
1. Content Browser > PCG > PCG Graph
2. Open PCG Graph Editor
---
## Basic Workflow
### Example: Forest Generation
#### 1. Create PCG Graph
**Node Setup:**
```
Input (Volume)
Surface Sampler (sample volume surface, points per m²: 0.5)
Density Filter (use texture mask or noise)
Static Mesh Spawner (tree meshes)
Output
```
#### 2. Assign Graph to Volume
1. Select PCG Volume
2. Details Panel > PCG Component > Graph = Your PCG Graph
3. Click "Generate" button
---
## Key Node Types
### Samplers (Point Generation)
#### Grid Sampler
- Regular grid of points
- Configure:
- **Grid Size**: Distance between points
- **Offset**: Random offset per point
#### Poisson Disk Sampler
- Random points with minimum distance
- Configure:
- **Points Per m²**: Density
- **Min Distance**: Spacing between points
#### Surface Sampler
- Points on mesh surfaces or landscape
- Configure:
- **Points Per m²**: Density
- **Surface Only**: Only surface, not volume
---
### Filters (Point Removal)
#### Density Filter
- Remove points based on density value
- Input: Texture or noise
- Use for: Biome masks, clearings, paths
#### Tag Filter
- Filter points by tag
- Use for: Conditional spawning
#### Bounds Filter
- Keep only points within bounds
- Use for: Limiting generation to specific areas
---
### Modifiers (Point Transformation)
#### Rotate
- Randomize point rotation
- Configure:
- **Min/Max Rotation**: Rotation range per axis
#### Scale
- Randomize point scale
- Configure:
- **Min/Max Scale**: Scale range
#### Project to Ground
- Snap points to landscape surface
---
### Spawners (Mesh/Actor Instantiation)
#### Static Mesh Spawner
- Spawn static meshes at points
- Configure:
- **Mesh List**: Array of meshes (random selection)
- **Culling Distance**: LOD/culling settings
#### Actor Spawner
- Spawn Blueprint actors at points
- Use for: Gameplay actors, interactive objects
---
## Data Sources
### Landscape
- Use landscape as input for sampling
- Automatically projects to landscape height
### Splines
- Generate content along splines (roads, rivers, paths)
- Example: Trees along path
### Textures
- Use textures as density masks
- Paint biomes, clearings, areas
---
## Biome Example (Mixed Forest)
### Graph Setup
```
Input (Landscape)
Surface Sampler (density: 1.0)
┌─────────────────┬─────────────────┐
│ Tree Biome │ Rock Biome │
│ (density > 0.5) │ (density < 0.5) │
├─────────────────┼─────────────────┤
│ Tree Spawner │ Rock Spawner │
└─────────────────┴─────────────────┘
Merge
Output
```
---
## Spline-Based Generation (Road with Trees)
### 1. Create PCG Graph
```
Spline Input
Spline Sampler (sample along spline)
Offset (offset from spline path)
Tree Spawner
Output
```
### 2. Add Spline Component to PCG Volume
1. PCG Volume > Add Component > Spline
2. Draw spline path
3. PCG Graph reads spline data
---
## Runtime Generation
### Trigger Generation from C++
```cpp
#include "PCGComponent.h"
UPCGComponent* PCGComp = /* Get PCG Component */;
PCGComp->Generate(); // Execute PCG graph
```
### Stream Generation (Large Worlds)
- PCG automatically streams with World Partition
- Only generates content in loaded cells
---
## Performance
### Optimization Tips
- Use **culling distance** on spawned meshes (LOD)
- Limit **density** (fewer points = better performance)
- Use **Hierarchical Instanced Static Meshes (HISM)** for repeated meshes
- Enable **streaming** for large worlds
### Debug Performance
```cpp
// Console commands:
// pcg.graph.debug 1 - Show PCG debug info
// stat pcg - Show PCG performance stats
```
---
## Common Patterns
### Forest with Clearings
```
Surface Sampler
Density Filter (noise texture with clearings)
Tree Spawner (pine, oak, birch)
```
---
### Rocks on Steep Slopes
```
Landscape Input
Surface Sampler
Slope Filter (angle > 30°)
Rock Spawner
```
---
### Props Along Road
```
Spline Input (road spline)
Spline Sampler
Offset (side of road)
Street Light Spawner
```
---
## Debugging
### PCG Debug Visualization
```cpp
// Console commands:
// pcg.debug.display 1 - Show points and generation bounds
// pcg.debug.colormode points - Color-code points
```
### Graph Debugging
- PCG Graph Editor > Debug > Show Debug Points
- Visualize points at each node in the graph
---
## Migration from UE 5.6 (Experimental) to 5.7 (Production)
### API Changes
```cpp
// ❌ OLD (5.6 experimental API):
// Some nodes renamed, API unstable
// ✅ NEW (5.7 production API):
// Stable node types, documented API
```
**Migration:** Rebuild PCG graphs using stable 5.7 nodes. Test thoroughly.
---
## Limitations
- **Not for gameplay logic**: Use Blueprints/C++ for game rules
- **Large graphs can be slow**: Optimize with filters and density reduction
- **Runtime generation overhead**: Pre-generate when possible
---
## Sources
- https://docs.unrealengine.com/5.7/en-US/procedural-content-generation-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/pcg-quick-start-in-unreal-engine/
- UE 5.7 Release Notes (PCG Production-Ready announcement)