class AMyCharacter : public ACharacter
{
GENERATED_BODY()
// 변수 선언
UPROPERTY(Replicated)
float Health;
// 복제 등록
virtual void GetLifetimeReplicatedProps(
TArray& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyCharacter, Health);
}
};
AMyActor()
{
bReplicates = true; // 필수
}
bReplicates가 true여야 변수 복제 동작class AMyCharacter : public ACharacter
{
// ReplicatedUsing 지정
UPROPERTY(ReplicatedUsing=OnRep_Health)
float Health;
// 콜백 함수
UFUNCTION()
void OnRep_Health()
{
// 값이 복제될 때마다 호출
UpdateHealthBar();
PlayHurtAnimation();
}
virtual void GetLifetimeReplicatedProps(
TArray& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyCharacter, Health);
}
};
OnRep_변수명 형식 권장// 모든 클라이언트에게 복제
DOREPLIFETIME(AMyCharacter, Health);
// 소유자(본인)에게만 복제
DOREPLIFETIME_CONDITION(AMyCharacter, Ammo, COND_OwnerOnly);
용도: 탄약, 돈, 개인 인벤토리 등 본인만 알면 되는 정보
// 소유자를 제외한 모든 클라이언트에게 복제
DOREPLIFETIME_CONDITION(AMyCharacter, EquippedWeapon, COND_SkipOwner);
용도: 본인은 이미 아는 정보, 다른 플레이어만 봐야 하는 것
// 최초 생성 시 한 번만 복제
DOREPLIFETIME_CONDITION(AMyCharacter, MaxHealth, COND_InitialOnly);
용도: 최대 체력, 캐릭터 레벨, 이름 등 불변 데이터
// SimulatedProxy에게만 복제
DOREPLIFETIME_CONDITION(AMyCharacter, ReplicatedMovement, COND_SimulatedOnly);
용도: 다른 플레이어들의 보간용 위치 데이터
// AutonomousProxy에게만 복제
DOREPLIFETIME_CONDITION(AMyCharacter, ServerPosition, COND_AutonomousOnly);
용도: 본인 캐릭터의 움직임 검증 데이터
COND_None // 조건 없음 (기본)
COND_InitialOnly // 초기 한 번만
COND_OwnerOnly // Owner만
COND_SkipOwner // Owner 제외
COND_SimulatedOnly // Simulated만
COND_AutonomousOnly // Autonomous만
COND_SimulatedOrPhysics // Simulated 또는 Physics
COND_InitialOrOwner // 초기 또는 Owner
COND_Custom // 커스텀 로직
COND_ReplayOrOwner // Replay 또는 Owner
COND_ReplayOnly // Replay만
COND_SimulatedOnlyNoReplay // Simulated, Replay 제외
COND_SimulatedOrPhysicsNoReplay // Simulated/Physics, Replay 제외
COND_SkipReplay // Replay 제외
COND_Never // 절대 복제 안함
| 조건 | 복제 대상 | 주요 용도 |
|---|---|---|
| 기본 (없음) | 모든 클라이언트 | 체력, 팀, 점수 |
| COND_OwnerOnly | 소유자만 | 탄약, 돈, 인벤토리 |
| COND_SkipOwner | 소유자 제외 | 장착 무기 메시 |
| COND_InitialOnly | 초기 한 번만 | 최대 체력, 레벨, 이름 |
| COND_SimulatedOnly | 다른 플레이어들 | 보간용 위치 |
| COND_AutonomousOnly | 본인 캐릭터 | 서버 위치 검증 |
class AMyCharacter : public ACharacter
{
// 선언
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire();
// 구현
void ServerFire_Implementation()
{
// 서버에서 실행되는 코드
SpawnBullet();
Ammo--;
}
// 검증 (치트 방지)
bool ServerFire_Validate()
{
// false 반환 시 클라이언트 킥
return Ammo > 0 && !IsReloading;
}
};
// 클라이언트에서 호출
void Fire()
{
ServerFire(); // 서버에 요청
}
특징:
Server로 시작 (관례)WithValidation으로 치트 방지 가능호출 조건 (3가지 모두 필요):
1. bReplicates = true
2. Local Role = AutonomousProxy (본인 캐릭터만)
3. Owner가 설정되어 있어야 함
class APlayerController : public APlayerController
{
// 선언
UFUNCTION(Client, Reliable)
void ClientShowMessage(const FString& Message);
// 구현
void ClientShowMessage_Implementation(const FString& Message)
{
// 해당 클라이언트에서만 실행
ShowNotification(Message);
}
};
// 서버에서 호출
void OnKill(APlayerController* Killer)
{
Killer->ClientShowMessage(TEXT("적 처치!"));
}
특징:
Client로 시작 (관례)class AGrenade : public AActor
{
// 선언
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayExplosion(FVector Location);
// 구현
void MulticastPlayExplosion_Implementation(FVector Location)
{
// 모든 클라이언트 + 서버에서 실행
SpawnParticle(Location);
PlaySound(Location);
}
};
// 서버에서 호출
void Explode()
{
MulticastPlayExplosion(GetActorLocation());
}
특징:
Multicast로 시작| RPC 타입 | 호출 위치 | 실행 위치 | 용도 | 예시 |
|---|---|---|---|---|
| Server | 클라이언트 | 서버 | 입력, 요청 | 발사, 아이템 획득 |
| Client | 서버 | 특정 클라 | 개인 알림 | 보상 획득 메시지 |
| NetMulticast | 서버 | 모든 곳 | 이벤트, 이펙트 | 폭발, 사운드 |
UFUNCTION(Server, Reliable)
void ServerPickupItem();
UFUNCTION(Client, Reliable)
void ClientShowReward();
특징:
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayFootstep();
// 변수 복제도 기본적으로 Unreliable
UPROPERTY(Replicated)
FVector Location;
특징:
enum ENetMode
{
NM_Standalone, // 싱글플레이
NM_DedicatedServer, // 전용 서버
NM_ListenServer, // 호스트 서버
NM_Client // 클라이언트
};
// 확인
ENetMode Mode = GetNetMode();
bool IsServer = HasAuthority();
enum ENetRole
{
ROLE_None, // 네트워크 없음
ROLE_SimulatedProxy, // 다른 플레이어 캐릭터
ROLE_AutonomousProxy, // 내 캐릭터
ROLE_Authority // 서버
};
// 확인
ENetRole LocalRole = GetLocalRole();
ENetRole RemoteRole = GetRemoteRole();
| Role | 의미 | 권한 | 예시 |
|---|---|---|---|
| Authority | 서버 | 모든 권한 | 서버의 모든 액터 |
| AutonomousProxy | 내 캐릭터 | 예측 가능 | 본인 조종 캐릭터 |
| SimulatedProxy | 다른 플레이어 | 받기만 | 다른 플레이어 캐릭터 |
| None | 복제 안됨 | 로컬만 | 이펙트, 파티클 |
서버에서 클라이언트A의 캐릭터:
클라이언트A에서 내 캐릭터:
클라이언트A에서 클라B의 캐릭터: