添加 claude code game studios 到项目

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

View File

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

View File

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

View File

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

View File

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