0. 개요

이전에 클릭으로 이동하기에서 클릭으로 목적지를 캐싱하는 부분을 기존의 함수인 CursorTrace로 대체할 수 있다.

코드를 리펙토링하여 재사용성, 효율성, 가독성을 개선한다.

 

 

1. 목적지 캐싱 수정 - AuraPlayerController

(1) CursorTrace 함수

FHitResult CursorHit를 멤버 변수로 저장한다.

void AAuraPlayerController::CursorTrace()
{
    // 트레이스 채널, 단순 충돌 확인, 반환되는 FHitResult 구조체의 주소
    GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, false, CursorHit);
    
    if (!CursorHit.bBlockingHit)
        return;

    LastActor = ThisActor;
    // 마우스 커서와 충돌한 액터 꺼내오기
    ThisActor = CursorHit.GetActor();

    if (LastActor != ThisActor)
    {
        if (LastActor)
            LastActor->UnHighlightActor();

        if (ThisActor)
            ThisActor->HighlightActor();
    }
}

 

 

(2) AbilityInputTagHeld 함수

새롭게 트레이스를 수행하던 부분을 기존의 CursorTrace에서 사용한 FHitResult CursorHit 구조체를 재사용한다.

    else // 이동
    {
        FollowTime += GetWorld()->GetDeltaSeconds();

        if (CursorHit.bBlockingHit)
        {
            // Hit.Location도 사용 가능
            CachedDestination = CursorHit.ImpactPoint;
        }

        if (APawn* ControlledPawn = GetPawn())
        {
            // 방향 벡터 구하기
            const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
            ControlledPawn->AddMovementInput(WorldDirection);
        }
    }

 

 

(3) 기타

- if 문에서 한 줄만 있는 코드 블럭은 중괄호를 제거하는 등, 컨벤션에 따라 코드를 정리한다.

- 디버그 구체를 출력하는 코드를 제거한다.

 

 

2. 메세지 팝업 디버그 - RPC (Remote Procedure Call)

멀티플레이 환경에서 아이템을 습득할 때 클라이언트에서 아이템 획득 메세지가 발생하지 않는 버그가 발생한다.

해당 버그를 수정하기 위해 커스텀 ASC를 확인한다.

 

(1) 문제 확인 - AuraAbilitySystemComponent

void UAuraAbilitySystemComponent::AbilityActorInfoSet()
{
    OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, &UAuraAbilitySystemComponent::EffectApplied);
}

이 델리게이트는 게임플레이 이펙트가 본인에게 적용될 때마다 서버 측에서 호출된다.

따라서 클라이언트 측이 아닌 서버에서만 메세지가 출력된다.

 

이를 해결하기 위해 이펙트 적용 함수를 RPC 함수로 수정한다.

 

 

(2) RPC 함수(Remote Procedure Call)

(2-1) 정의

서버 - 클라이언트 사이의 통신을 간소화하기 위해 도입됨

 

(2-2) 종류

- 클라이언트 호출(Client RPC) : 서버에서 호출해서 클라이언트에서 작동

- 서버 호출(Server RPC) : 클라이언트에서 호출해서 서버에서 작동

- 멀티캐스트 호출(Multicast RPC) : 서버에서 호출해서 연결된 모든 클라이언트에서 작동

 

(2-3) 속성

RPC 속성을 이용해 호출 대상을 지정할 수 있다.

- Server, Client, NetMulticast

 

RPC 속성을 이용해 신뢰성을 보장할 수 있다.

- Reliable(패킷 손실시 받을 때까지 재전송), UnReliable(성능적으로 우위)

 

(2-4) 적용

UFUNCTION 매크로를 이용해 클라이언트에서 실행되는 함수로 설정한다.

UFUNCTION의 Reliable 옵션으로 패킷 손실이 발생해도 클라이언트가 요청을 수행할 때까지 패킷을 재전송한다.

protected:

	UFUNCTION(Client, Reliable)
	// 이펙트 적용 콜백 함수
	void ClientEffectApplied(UAbilitySystemComponent* AbilitySystemComponent, const FGameplayEffectSpec& EffectSpec, FActiveGameplayEffectHandle ActiveEffectHandle);
};
void UAuraAbilitySystemComponent::AbilityActorInfoSet()
{
    OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, &UAuraAbilitySystemComponent::ClientEffectApplied);
}

 

void UAuraAbilitySystemComponent::ClientEffectApplied_Implementation(UAbilitySystemComponent *AbilitySystemComponent, const FGameplayEffectSpec &EffectSpec, FActiveGameplayEffectHandle ActiveEffectHandle)
{
    // 이펙트 적용 시 무엇을 BroadCast 할 것인가??
    // Tag가 적절
    FGameplayTagContainer TagContainer;
    EffectSpec.GetAllAssetTags(TagContainer);

    EffectAssetTags.Broadcast(TagContainer);
}

_Implementation이 붙은 함수는 클라이언트에서 실제로 작동하게 되는 코드이다.

 

(2-5) 작동 흐름

- 클라이언트 RPC

서버에서 (함수이름) 함수  호출 - 언리얼 내부적으로 클라이언트에게 전달 - 클라이언트에서 (함수이름)_Implementation 함수 호출

 

- 서버 RPC

클라이언트에서 (함수이름) 함수 호출 - 언리얼 내부적으로 서버에게 전달 - 서버에서 (함수이름)_Implementation 함수 호출

 

 

(2-6) 주의점

- 서버 호출(서버 RPC)는 서버 권한이 있는 Actor에서만 작동

- 클라이언트가 로컬로 실행 중이어도 서버 RPC는 반드시 서버를 통해야 함