PART 5 - 강의 2/2
GameplayCue 네트워크 최적화
Local Only와 Minimal Replication
01
Cue 네트워크 동작
RPC와 복제 이해
GameplayCue는 기본적으로 서버에서 Multicast RPC를 통해 모든 클라이언트에 전달됩니다. 하지만 모든 이펙트가 네트워크 복제가 필요한 것은 아닙니다.
기본 네트워크 흐름
// 기본 GameplayCue 네트워크 흐름
// 1. 서버에서 GameplayEffect 적용
// 2. Effect에 연결된 Cue Tag 감지
// 3. Multicast RPC로 모든 클라이언트에 전달
// 4. 각 클라이언트에서 Cue 실행
// 문제점:
// - 불필요한 대역폭 사용 (1인칭 이펙트 등)
// - 동일 Cue가 여러 번 전송될 수 있음
// 해결책:
// - Local Only 실행
// - Minimal Replication
// - Cue 태그 압축
02
Local Only 실행
클라이언트 전용 이펙트
Local Only Cue 실행
// 서버 복제 없이 로컬에서만 Cue 실행
void UGA_LocalEffect::ExecuteLocalOnlyCue()
{
// 로컬 플레이어 확인
if (!IsLocallyControlled()) return;
FGameplayCueParameters CueParams;
CueParams.Location = GetAvatarActorFromActorInfo()->GetActorLocation();
// ExecuteGameplayCueLocal - 복제 없음
UAbilitySystemComponent* ASC = GetAbilitySystemComponentFromActorInfo();
ASC->ExecuteGameplayCueLocal(
FGameplayTag::RequestGameplayTag(FName("GameplayCue.Player.FirstPerson.Hit")),
CueParams);
}
// 적합한 사용 사례:
// - 1인칭 화면 이펙트 (피격 시 빨간 화면)
// - UI 피드백
// - 로컬 카메라 쉐이크
// - 자신에게만 보이는 이펙트
// Actor Cue에서 Local Only 설정
UCLASS()
class AGC_LocalScreenEffect : public AGameplayCueNotify_Actor
{
GENERATED_BODY()
public:
AGC_LocalScreenEffect()
{
// 복제하지 않음
bAutoDestroyOnRemove = true;
bUniqueInstancePerInstigator = false;
// 네트워크 관련 - 서버에서 스폰하지 않음
SetReplicates(false);
}
};
Local vs Replicated 선택 기준
다른 플레이어가 볼 필요가 없는 이펙트(UI, 1인칭)는 Local Only로, 모든 플레이어가 봐야 하는 이펙트(폭발, 스킬)는 Replicated로 실행하세요.
03
Minimal Replication
GameplayEffect 복제 최소화
Minimal Replication Mode
// ASC Replication Mode 설정
UCLASS()
class AMyPlayerState : public APlayerState
{
public:
AMyPlayerState()
{
// Mixed Mode - 오너에게만 전체 복제
AbilitySystemComponent->SetReplicationMode(
EGameplayEffectReplicationMode::Mixed);
}
};
// Replication Mode 종류
enum class EGameplayEffectReplicationMode : uint8
{
// 모든 Effect를 모든 클라이언트에 복제
Full,
// Effect는 오너에게만, Cue와 Tag는 모두에게
Mixed,
// Cue와 Tag만 복제, Effect 자체는 복제 안 함
Minimal
};
// Minimal 모드에서 Cue 동작
// 1. 서버에서 Effect 적용
// 2. Effect 자체는 복제하지 않음
// 3. Cue Tag만 RPC로 전송
// 4. 클라이언트에서 Cue 실행
// 대역폭 절약 효과:
// - Full: Effect 전체 데이터 (수십~수백 바이트)
// - Minimal: Tag만 (4바이트 정도)
04
Cue Manager 최적화
전역 Cue 관리
GameplayCue Manager 설정
// DefaultGame.ini에서 Cue Manager 설정
[/Script/GameplayAbilities.AbilitySystemGlobals]
// Cue 경로 설정 (게임 시작 시 미리 로드)
+GameplayCueNotifyPaths=/Game/Effects/GameplayCues
// 커스텀 Cue Manager 사용
UCLASS()
class UMyGameplayCueManager : public UGameplayCueManager
{
GENERATED_BODY()
public:
// 비동기 로드 최적화
virtual void OnCreated() override
{
Super::OnCreated();
// 자주 사용되는 Cue 미리 로드
LoadGameplayCueNotifyPaths();
}
// Cue 풀링 (재사용)
virtual AGameplayCueNotify_Actor* GetInstancedCueActor(
AActor* TargetActor,
UClass* CueClass,
const FGameplayCueParameters& Parameters) override
{
// 풀에서 재사용 가능한 Actor 찾기
// 없으면 새로 스폰
return Super::GetInstancedCueActor(TargetActor, CueClass, Parameters);
}
};
// AbilitySystemGlobals에서 등록
void UMyAbilitySystemGlobals::InitGlobalData()
{
Super::InitGlobalData();
GameplayCueManager = NewObject<UMyGameplayCueManager>(this);
}
05
배치 및 압축
다수 Cue 효율적 전송
Cue 배치 처리
// 여러 Cue를 하나의 RPC로 묶기
void UMyAbilitySystemComponent::BatchExecuteGameplayCues(
const TArray<FGameplayTag>& CueTags,
const FGameplayCueParameters& Parameters)
{
// 로컬 실행
for (const FGameplayTag& Tag : CueTags)
{
HandleGameplayCue(nullptr, Tag, EGameplayCueEvent::OnExecute, Parameters);
}
// 서버라면 클라이언트에 배치 전송
if (GetOwnerRole() == ROLE_Authority)
{
// NetMulticast로 한 번에 전송
NetMulticast_BatchedCues(CueTags, Parameters);
}
}
// Cue 태그 압축
// GameplayTag는 FName 기반이라 문자열 전송 시 비효율적
// NetSerialize를 통해 인덱스 기반으로 전송
// 프로젝트 설정에서 태그 압축 활성화
// Project Settings > GameplayAbilities >
// Replicate GameplayCue Tags via Abbreviated Name = true
대역폭 모니터링
stat Net과 Network Profiler를 사용하여 Cue RPC 대역폭을 모니터링하세요. 예상보다 많은 대역폭을 사용한다면 Local Only나 배치 처리를 고려하세요.
SUMMARY
핵심 요약
- ExecuteGameplayCueLocal: 복제 없이 로컬에서만 실행
- Minimal Replication: Effect 복제 없이 Cue Tag만 전송
- GameplayCue Manager: 미리 로드, 풀링으로 최적화
- 배치 처리: 여러 Cue를 하나의 RPC로 묶기
- 태그 압축: 인덱스 기반 전송으로 대역폭 절약
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: Cue 최적화 설정
MinimalReplication 모드에서 GameplayCue가 올바르게 트리거되는지 확인하세요. GE의 bSuppressStackingCues로 스택 변경 시 불필요한 Cue 재생을 방지하세요.
실습 2: Cue Manager 설정
DefaultEngine.ini에서 GameplayCuePaths를 설정하고, GameplayCueManager의 로딩 전략(동기/비동기)을 구성하세요.
심화 과제
undefined