인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김수영님의 프로필 이미지

작성한 질문수

이득우의 언리얼 프로그래밍 Part3 - 네트웍 멀티플레이 프레임웍의 이해

13강 캐릭터 무브먼트의 확장

CompressedFlags를 이용한 InputThrottle, InputSteering 전달 방법 질문

작성

·

61

0

기본적으로 지원하는 단순 이동이 아니라 자동차처럼 Throttle와 Steering을 구현하려고 합니다.

알려주신 방법을 응용해 다음과 같이 구현했습니다.

 

USTRUCT(BlueprintType, Blueprintable)

struct FDriveInput

{

	GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)

	float Throttle = 0.0f;

	

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)

	float Steering = 0.0f;

	uint8 GetCompressedFlags() const

	{

		uint8 Compressed = 0;

		int32 ThrottleBits = FMath::Clamp(FMath::CeilToInt((Throttle + 1.0f) * 7.5f), 0, 15);

		int32 SteeringBits = FMath::Clamp(FMath::CeilToInt((Steering + 1.0f) * 7.5f), 0, 15);

		Compressed |= (ThrottleBits << 4);

		Compressed |= (SteeringBits & 0x0F);

		return Compressed;

	}

	void SetFromCompressedFlags(uint8 Flags)

	{

		int32 ThrottleBits = (Flags >> 4) & 0x0F;

		int32 SteeringBits = Flags & 0x0F;

		Throttle = (float(ThrottleBits) / 7.5f) - 1.0f;

		Steering = (float(SteeringBits) / 7.5f) - 1.0f;

	}
};

 

FNetworkPredictionData_Client_TitanCharacter::FNetworkPredictionData_Client_TitanCharacter(const UCharacterMovementComponent& ClientMovement)
	: Super(ClientMovement)
{

}

FSavedMovePtr FNetworkPredictionData_Client_TitanCharacter::AllocateNewMove()
{
	return FSavedMovePtr(new FSavedMove_TitanCharacter);
}

void FSavedMove_TitanCharacter::Clear()
{
	Super::Clear();
	DriveInput.Steering = 0.0f;
	DriveInput.Throttle = 0.0f;
}

void FSavedMove_TitanCharacter::SetInitialPosition(ACharacter* Character)
{
	Super::SetInitialPosition(Character);

	UTitanCharacterMovementComponent* Movement = Cast<UTitanCharacterMovementComponent>(Character->GetCharacterMovement());
	if (Movement)
	{
		DriveInput = Movement->DriveInput;
	}
}

uint8 FSavedMove_TitanCharacter::GetCompressedFlags() const
{
	uint8 Result = Super::GetCompressedFlags();
	Result |= DriveInput.GetCompressedFlags();
	return Result;
}

 

}

void UTitanCharacterMovementComponent::OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity)
{
	UpdateWithDriveState(DeltaSeconds, DriveFlow.DriveState);
}

void UTitanCharacterMovementComponent::UpdateFromCompressedFlags(uint8 Flags)
{
	Super::UpdateFromCompressedFlags(Flags);
	DriveInput.SetFromCompressedFlags(Flags);
}

 

UpdateWithDriveState 는 실제 캐릭터가 InputThrottle와 InputSteering을 가지고 움직이는 부분입니다.
이렇게 하니까 다른 플래그와 겹쳐 아무런 입력을 하지 않았는데 점프를 한다거나, 손실압축의 특성때문에 입력을 하지 않아도 0이 아닌 다른 값이 전달되는 문제가 있었습니다.

관련해서 도움을 받고 싶습니다. VehicleMovementComponent도 알아봤는데, CharacterMovementComponent를 확장해서 만들 수 있는 방법은 없는건가요?
제가 찾아보면 좋을 법한 키워드 또는 해결방법을 알고 싶습니다.

답변 1

0

이득우님의 프로필 이미지
이득우
지식공유자

안녕하세요.
보내주신 코드의 일부만으로는 제가 정확히 도움드리기는 힘들 것 같습니다. 다만 캐릭터 무브먼트 컴포넌트 자체가 자동차와는 무관하게 설계된 것이라 이를 확장하는 것은 별로 추천드리고 싶지 않네요.
ChaosVehicleMovementComponent가 플러그인으로 분리되어 있고 네트웍 동기화를 지원하다보니, 이를 분석하는 것이 장기적으로는 구현하고자 것에 도움이 될 것으로 보여집니다.