본문으로 건너뛰기
Unreal Engine 멀티플레이LESSON 25

아이템 스폰, 획득, 파괴 복제하기

난이도입문 → 초급
예상 시간85분
선수지식24강의 서버 체력 상태

25강. 아이템 스폰, 획득, 파괴 복제하기

1. 이번 강의에서 해결할 문제​

두 클라이언트가 같은 회복 아이템에 동시에 닿아 둘 다 회복하거나, 클라이언트가 로컬 Destroy해 자기 화면에서만 사라집니다. 아이템 생성·획득 판정·효과와 파괴는 하나의 서버 트랜잭션처럼 처리해야 합니다.

2. 학습 목표​

3. 핵심 개념​

아이템 Actor는 서버가 Spawn하고 bReplicates로 존재를 전달합니다. Overlap 콜백은 여러 복사본에서 발생할 수 있으므로 실제 획득 로직은 HasAuthority()에서만 실행합니다. 먼저 소비 상태를 잠그고 대상·거리·효과 가능 여부를 확인한 뒤 서버 HealthComponent를 변경하고 Actor를 Destroy합니다.

아이템이 사라진다는 현재 상태는 서버 Destroy가 전파합니다. 짧은 획득 파티클은 서버 승인 뒤 Multicast할 수 있지만 파티클이 유실돼도 회복과 아이템 제거는 유지돼야 합니다.

4. 단계별 실습​

CaptureHealthPickup.h
UCLASS()
class CAPTUREARENA_API ACaptureHealthPickup : public AActor
{
GENERATED_BODY()

public:
ACaptureHealthPickup();

protected:
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;

UFUNCTION(NetMulticast, Unreliable)
void Multicast_PlayConsumedFx(FVector_NetQuantize Location);

UPROPERTY(VisibleAnywhere)
TObjectPtr<USphereComponent> Trigger;

UPROPERTY(EditDefaultsOnly, Category = "Pickup",
meta = (ClampMin = "1.0"))
float HealAmount = 30.0f;

private:
bool bConsumed = false; // 서버에서만 판정하는 일회성 잠금
};
CaptureHealthPickup.cpp
ACaptureHealthPickup::ACaptureHealthPickup()
{
PrimaryActorTick.bCanEverTick = false;
bReplicates = true;

Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("Trigger"));
SetRootComponent(Trigger);
Trigger->SetSphereRadius(90.0f);
}

void ACaptureHealthPickup::NotifyActorBeginOverlap(AActor* OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
if (!HasAuthority() || bConsumed || !IsValid(OtherActor)) return;

UCaptureHealthComponent* Health =
OtherActor->FindComponentByClass<UCaptureHealthComponent>();
if (!Health || !Health->CanReceiveHealing()) return;

bConsumed = true;
Trigger->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Health->HealOnServer(HealAmount);
Multicast_PlayConsumedFx(GetActorLocation());
Destroy();
}

void ACaptureHealthPickup::Multicast_PlayConsumedFx_Implementation(
FVector_NetQuantize Location)
{
if (GetNetMode() != NM_DedicatedServer)
{
SpawnPickupFx(Location);
}
}

Spawner는 GameMode나 서버 권한 Spawner Actor에서 GetWorld()->SpawnActor를 호출합니다. Respawn Timer도 서버에만 둡니다. 클라이언트 요청 기반 Pickup이라면 서버가 Overlap 또는 거리로 다시 확인하고 Client Actor 포인터를 믿지 않습니다.

5. 코드가 동작하는 이유​

서버의 첫 유효 Overlap이 bConsumed를 먼저 설정해 같은 프레임의 두 번째 콜백을 막습니다. 서버 Health를 변경하고 서버 Actor를 Destroy하므로 모든 클라이언트가 같은 체력과 아이템 존재 상태에 수렴합니다. Multicast 효과는 결과와 분리돼 유실돼도 중복 획득이 생기지 않습니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

8. 이해 점검 질문 3개​

9. 핵심 요약​

MINI QUIZ

아이템 스폰, 획득, 파괴 복제하기 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“아이템 스폰, 획득, 파괴 복제하기” 실습 결과를 해석하는 올바른 기준은 무엇인가요?
  2. 문제 2‘효과 적용 뒤 bConsumed 설정’ 실수를 판단할 때 “아이템 스폰, 획득, 파괴 복제하기” 강의가 제시한 기준은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

25강. 아이템 스폰, 획득, 파괴 복제하기 미완료 상태