[Unreal] US_Character Class 코드 분석(RPC 상호작용)
이번 코드는 문을 열기 위해 작성된 코드이다. 이를 위해 트레이스를 통해 앞에 어떤 물체가 있는지 검출한 후, 충돌된 물체를 감지하는 역할을 할 것이다.
액터 권한 검출
void AUS_Character::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (GetLocalRole() != ROLE_Authority)
return;
...
[UE5] Actor Role, Remote Role
네트워크 게임플레이에서 액터의 role과 remote role은 '이 액터의 상태를 변경하거나 RPC를 수행할 권한이 어느 기기에 있는가 를 결정한다.
velog.io
GetLocalRole(): 현재 실행 중인 로컬 시스템, 즉 컴퓨터가 서버인지 클라이언트인지 확인한다.
ROLE_Authority: 로컬 시스템이 액터에 대한 완전한 권한을 가짐을 의미한다. 즉, 서버라는 의미이다.
해당 코드는 자신이 서버인지 확인한 후, 뒤에 코드를 실행하기 위한 필터 역할을 한다.
트레이스 파라미터 설정
FHitResult HitResult;
FCollisionQueryParams QueryParams;
QueryParams.bTraceComplex = true;
QueryParams.AddIgnoredActor(this);
auto SphereRadius = 50.f;
auto StartLocation = GetActorLocation() + GetActorForwardVector() * 150.f;
auto EndLocation = StartLocation + GetActorForwardVector() * 500.f;
FHitResult: 충돌 지점과 같은 hit 정보를 포함하는 구조체 이다.
FCollisionQueryParams: 충돌 함수에 전달되는 매개변수를 정의한다.
bTraceComplex: 언리얼 문서에서는 복잡한 충돌 검사라 적혀있다. 이때 복잡한 충돌 검사는 명확한 기준을 찾기 어렵지만 언리얼 개발자 포럼에서는 "Trace Complex가 폴리곤 기반 Trace인 반면 Basic은 충돌 기반"이라 설명한다.
AddIgnoredActor: 자신을 충돌에서 제외한다.
SphereRadius: 탐지 구 반경
StartLocation: 시작점(캐릭터 앞 150유닛)
EndLocation: 종료지점(시작점 기준 500유닛 앞)
구체 트레이스 실행
auto IsHit = UKismetSystemLibrary::SphereTraceSingle(
GetWorld(),
StartLocation,
EndLocation,
SphereRadius,
UEngineTypes::ConvertToTraceType(ECC_WorldStatic),
false,
TArray<AActor*>(),
EDrawDebugTrace::ForOneFrame,
HitResult,
true
);
언리얼 문서를 통해 해당 정보를 얻을 수 있다. 특별히 봐야 할 부분은 없으므로 간단히 작성하고자 한다.
ConvertToTraceType: 충돌 유형을 정한다.(정적 오브젝트만 검출)
TArray<AActor*>(): 추가 제외 액터 없음
EDrawDebugTrace::ForOneFrame: 1프레임 동안 디버그 표시
결과 처리
if (IsHit && HitResult.GetActor()->GetClass()->ImplementsInterface(UUS_Interactable::StaticClass()))
{
DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, SphereRadius, 12, FColor::Magenta, false, 1.f);
InteractableActor = HitResult.GetActor();
}
else
{
InteractableActor = nullptr;
}
해당 코드는 충돌 지점을 분홍색 구체로 시각적으로 표기하고, InteractableActor에 저장하는 것이다.
RPC
void AUS_Character::Interact(const FInputActionValue& Value)
{
Interact_Server();
}
void AUS_Character::Interact_Server_Implementation()
{
if (InteractableActor)
{
IUS_Interactable::Execute_Interact(InteractableActor, this);
}
}
RPC 코드는 이전 글과 유사하지만, 인터페이스 호출 방법이 다양하다. 해당 내용은 아래 글을 참고하면 좋다.
언리얼 interface c++ 호출방법
상속클래스.h void Interact_Implementation() override; //블루프린트에서도 사용가능// virtual void InteractPure() override; //c++에서만 사용함// 상속클래스.cpp void ACharacter::Interact_Implementation() { UE_Log(LogTemp, Warning,
codakcoo.tistory.com