기록
240418 플레이어 RPC를 사용하여 사이즈 변경 동기화
hayo_su
2024. 4. 21. 21:47
문제상황
사이즈를 조정하였을 때 서버와 클라이언트가 동기화 되지않는다.
해결과정
1. 리플리케이트 설정 확인
메시와 캡슐 컴포넌트에 대한 컴포넌트 리플리케이트 설정을 true로 변경한다.
2. 서버권한 유무에 따라 키를 다른 함수로 바인딩 시킨다.
if (PlayerInput != nullptr)
{
if(true == HasAuthority())
{
PlayerInput->BindAction(LeftMAction, ETriggerEvent::Triggered, this, &ACody::ChangeSmallSize);
PlayerInput->BindAction(RightMAction, ETriggerEvent::Triggered, this, &ACody::ChangeBigSize);
}
else
{
PlayerInput->BindAction(LeftMAction, ETriggerEvent::Triggered, this, &ACody::ChangeServerSmallSize);
PlayerInput->BindAction(RightMAction, ETriggerEvent::Triggered, this, &ACody::ChangeServerBigSize);
}
}
3. 서버인 캐릭터인 경우클라이언트 실행으로만 설정한다.
캡슐컴포넌트가 리플리케이트 되어있으므로 클라이언트 실행으로만 설정해도 동기화가 된다.
// .h
UFUNCTION(Client, Reliable)
void ChangeBigSize();
UFUNCTION(Client, Reliable)
void ChangeSmallSize();
4. 클라이언트 캐릭터인 경우 서버로 함수를 실행시켜 서버의 캐릭터1을 변경해야 한다.
다음과 같이 서버에서 실행할 수 있도록 설정하고
//.h
UFUNCTION(Server, Reliable, WithValidation)
void ChangeServerBigSize();
UFUNCTION(Server, Reliable, WithValidation)
void ChangeServerSmallSize();
Validate()함수와 Implementatioin()함수를 추가해 주었다.
// .cpp
bool ACody::ChangeServerBigSize_Validate()
{
return true;
}
void ACody::ChangeServerBigSize_Implementation()
{
if (!GetCharacterMovement()->IsFalling())
{
IsSprint = false;
switch (CurCodySize)
{
case CodySize::BIG:
{
break;
}
case CodySize::NORMAL:
{
NextCodySize = CodySize::BIG;
break;
}
case CodySize::SMALL:
{
NextCodySize = CodySize::NORMAL;
break;
}
default:
break;
}
}
}
5. 변경 시점이 꼬이지 않도록 tick에서 서버 여부를 확인하고,
사이즈 변경 여부를 확인하여 서버쪽에서 변경할 수 있도록 하였다.
void ACody::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
GetCapsuleComponent()->MarkRenderStateDirty();
//Scale Check
if (true == HasAuthority())
{
if (CurCodySize != NextCodySize)
{
switch (NextCodySize)
{
case CodySize::NONE:
break;
case CodySize::BIG:
`
`
`
`
break;
default:
break;
}
CurCodySize = NextCodySize;
}
}
}
결과
서버와 클라이언트 사이즈 변경이 동기화되었다.