Files
pixelheros/docs/engine-reference/unreal/modules/networking.md
2026-05-15 14:52:29 +08:00

410 lines
8.8 KiB
Markdown

# 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/