添加 claude code game studios 到项目
This commit is contained in:
210
docs/engine-reference/unreal/PLUGINS.md
Normal file
210
docs/engine-reference/unreal/PLUGINS.md
Normal 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
|
||||
54
docs/engine-reference/unreal/VERSION.md
Normal file
54
docs/engine-reference/unreal/VERSION.md
Normal 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/
|
||||
150
docs/engine-reference/unreal/breaking-changes.md
Normal file
150
docs/engine-reference/unreal/breaking-changes.md
Normal 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
|
||||
340
docs/engine-reference/unreal/current-best-practices.md
Normal file
340
docs/engine-reference/unreal/current-best-practices.md
Normal 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
|
||||
170
docs/engine-reference/unreal/deprecated-apis.md
Normal file
170
docs/engine-reference/unreal/deprecated-apis.md
Normal 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
|
||||
292
docs/engine-reference/unreal/modules/animation.md
Normal file
292
docs/engine-reference/unreal/modules/animation.md
Normal 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/
|
||||
289
docs/engine-reference/unreal/modules/audio.md
Normal file
289
docs/engine-reference/unreal/modules/audio.md
Normal 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/
|
||||
288
docs/engine-reference/unreal/modules/input.md
Normal file
288
docs/engine-reference/unreal/modules/input.md
Normal 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/
|
||||
338
docs/engine-reference/unreal/modules/navigation.md
Normal file
338
docs/engine-reference/unreal/modules/navigation.md
Normal 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/
|
||||
409
docs/engine-reference/unreal/modules/networking.md
Normal file
409
docs/engine-reference/unreal/modules/networking.md
Normal 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/
|
||||
283
docs/engine-reference/unreal/modules/physics.md
Normal file
283
docs/engine-reference/unreal/modules/physics.md
Normal 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/
|
||||
297
docs/engine-reference/unreal/modules/rendering.md
Normal file
297
docs/engine-reference/unreal/modules/rendering.md
Normal 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/
|
||||
353
docs/engine-reference/unreal/modules/ui.md
Normal file
353
docs/engine-reference/unreal/modules/ui.md
Normal 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/
|
||||
389
docs/engine-reference/unreal/plugins/common-ui.md
Normal file
389
docs/engine-reference/unreal/plugins/common-ui.md
Normal 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/
|
||||
386
docs/engine-reference/unreal/plugins/gameplay-ability-system.md
Normal file
386
docs/engine-reference/unreal/plugins/gameplay-ability-system.md
Normal 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)
|
||||
321
docs/engine-reference/unreal/plugins/gameplay-camera-system.md
Normal file
321
docs/engine-reference/unreal/plugins/gameplay-camera-system.md
Normal 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.
|
||||
356
docs/engine-reference/unreal/plugins/pcg.md
Normal file
356
docs/engine-reference/unreal/plugins/pcg.md
Normal 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)
|
||||
Reference in New Issue
Block a user