달리기 애니메이션
달리기 애니메이션을 연결하려면 Mesh 컴포넌트의 디테일에서 Animation의 Anim Class에 작성한 Animation BluePrint를 할당한다.
해당 애니메이션은 Speed를 기준으로 동작하는데, 이 변수를 서버에서 받아 사용하므로 클라이언트에서는 값이 갱신되지 않아 오류가 발생한다. 이를 해결하기 위해 코드를 수정해야 한다.
US_Character.h
UFUNCTION(NetMulticast, Reliable)
void SprintStart_Client();
UFUNCTION(NetMulticast, Reliable)
void SprintEnd_Client();
US_Character.cpp
void AUS_Character::SprintStart_Server_Implementation()
{
SprintStart_Client();
}
void AUS_Character::SprintEnd_Server_Implementation()
{
SprintEnd_Client();
}
void AUS_Character::SprintStart_Client_Implementation()
{
if (GetCharacterStats())
{
GetCharacterMovement()->MaxWalkSpeed = GetCharacterStats()->SprintSpeed;
}
}
void AUS_Character::SprintEnd_Client_Implementation()
{
if (GetCharacterStats())
{
GetCharacterMovement()->MaxWalkSpeed = GetCharacterStats()->WalkSpeed;
}
}
SprintStart_Server_Implementation을 보면 NetMulticast로 선언된 _Client()를 호출하고 있다. NetMulticast는 서버에서 오브젝트가 함수를 호출하면, 서버와 함수를 호출하는 오브젝트의 모든 클라이언트 버전에서 실행된다. 이러한 특징으로 자신뿐만 아니라 다른 클라이언트에서도 오류 없이 처리할 수 있게 된다.
던지기 애니메이션
US_WeaponProjectileComponent.h
UFUNCTION(NetMulticast, Unreliable)
void Throw_Client();
이번 UFUNCTION을 주목해야 하는 점은 Unreliable로 설정된 부분이다. 애니메이션은 단지 시각적인 효과일 뿐이므로, 네트워크상에서 데이터 손실이 발생해도 괜찮기 때문에 이러한 설정을 가지게 되었다.
US_WeaponProjectileComponent.cpp
void UUS_WeaponProjectileComponent::Throw_Client_Implementation()
{
const auto Character = Cast<AUS_Character>(GetOwner());
if (ThrowAnimation != nullptr)
{
if (const auto AnimInstance = Character->GetMesh()->GetAnimInstance(); AnimInstance != nullptr)
{
AnimInstance->Montage_Play(ThrowAnimation, 1.f);
}
}
}
- AnimInstance->Montage_Play(ThrowAnimation, 1.f): 지정된 애니메이션 몽타주를 1배속으로 재생하는 것을 의미한다.
US_WeaponProjectileComponent.cpp
void UUS_WeaponProjectileComponent::Throw_Server_Implementation()
{
if (ProjectileClass)
{
Throw_Client();
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, [&]()
{
const auto Character = Cast<AUS_Character>(GetOwner());
const auto ProjectileSpawnLocation = GetComponentLocation();
const auto ProjectileSpawnRotation = GetComponentRotation();
auto ProjectileSpawnParams = FActorSpawnParameters();
ProjectileSpawnParams.Owner = GetOwner();
ProjectileSpawnParams.Instigator = Character;
GetWorld()->SpawnActor<AUS_BaseWeaponProjectile>(ProjectileClass, ProjectileSpawnLocation, ProjectileSpawnRotation, ProjectileSpawnParams);
}, .4f, false);
}
}
물체를 던질 때 미리 스폰되어 던지는 것은 어색한 시각적 효과를 주므로, 스폰 로직을 약간 지연시켜야 한다. 이를 위해 약 0.4초 지연시킨다.
'Unreal > 언리얼 엔진 5로 개발하는 멀티플레이어 게임(Book)' 카테고리의 다른 글
[Unreal] 애니메이션 에셋 생성 (0) | 2025.04.04 |
---|---|
[Unreal] US_WeaponProjectileComponent.cpp 코드 분석 (0) | 2025.04.04 |
[Unreal] US_BaseWeaponProjectile.cpp 코드 분석 (0) | 2025.04.02 |
[Unreal] US_Minion.cpp (체력) (0) | 2025.04.02 |
[Unreal] 경보 시스템 코드 분석 (0) | 2025.04.01 |