반응형
FABRIK IK
FABRIK (Forward and Backward Reaching Inverse Kinematics)는 효율적인 Inverse Kinematics (IK) 해결 방법 중 하나로, 복잡한 연산 없이도 연결된 관절 구조를 효율적으로 조작할 수 있게 해 줍니다.
구현 과정
무기별 스켈레탈 메쉬 - 스켈레톤 트리의 Root_Bone에 소켓 추가 LeftHandSocket로 이름 수정
플레이어 AnimInstance의 업데이트에서 FABRIK IK코드 구현
void UBlasterAnimInstance::NativeUpdateAnimation(float DeltaTime)
{
Super::NativeUpdateAnimation(DeltaTime);
// 처음 널이라면 얻어옴
if (BlasterCharacter == nullptr)
{
BlasterCharacter = Cast<ABlasterCharacter>(TryGetPawnOwner());
}
// 위에서 얻어왔는데도 널이라면 리턴
if (BlasterCharacter == nullptr)
return;
.....
bWeaponEquipped = BlasterCharacter->IsWeaponEquipped();
EquippedWeapon = BlasterCharacter->GetEquippedWeapon();
......
// FABRIK IK
// 무기를 장착했고 장착한 무기가 있고 장착한 무기의 스켈레탈메쉬가 있고 플레이어의 스켈레탈 메쉬도 있을경우에만 허용
if (bWeaponEquipped && EquippedWeapon && EquippedWeapon->GetWeaponMesh() && BlasterCharacter->GetMesh())
{
// 소켓의 정보를 월드위치로 얻어옴
LeftHandTransform = EquippedWeapon->GetWeaponMesh()->GetSocketTransform(FName("LeftHandSocket"), ERelativeTransformSpace::RTS_World);
// 값을 추출해 저장하기 위한 변수
FVector OutPosition;
FRotator OutRotation;
//TransformToBoneSpace 함수를 사용하여 왼손의 위치와 회전을 무기의 소켓 위치로 변환
// 해당 함수는 지정한 본 ("hand_r")의 공간에 대한 상대적인 변환을 계산합니다.
BlasterCharacter->GetMesh()->TransformToBoneSpace(FName("hand_r"), LeftHandTransform.GetLocation(),
FRotator::ZeroRotator, OutPosition, OutRotation);
// 계산된 위치 OutPosition와 회전 OutRotation으로 LeftHandTransform의 위치와 회전을 업데이트
LeftHandTransform.SetLocation(OutPosition);
LeftHandTransform.SetRotation(FQuat(OutRotation));
}
}
위 코드와 AnimBP 구현한 상태에서 아래와 같이 게임 시작한 뒤 F8 눌러 자유시점 변경 후 hand_l 위치를 무기에 딱 맞게끔 LeftHandSocket의 위치 조절
AimOffset
아래와 같이 9방향에 대한 0프레임짜리 Aim생성
AnimOffset블루프린트 생성
AnimBP - AnimOffset 캐시포즈 생성 및 구현
FootStepSound
FootStepSound는 플레이어 바닥의 Physics Mat을 알아내 Material에 따른 각기 다른 발소리를 출력하도록 구현하였고
플레이어의 이동속도에 따라 발소리의 크기를 달리하여 좀 더 TPS적이고 생동감 있도록 구현하였습니다.
지난 UE5 Action RPG 구현했던 부분 사용했는데 일부 변경해 사용했습니다.
void UFootStepAnimNotify::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
const FAnimNotifyEventReference& EventReference)
{
ABlasterCharacter* Character = MeshComp->GetOwner<ABlasterCharacter>();
if (!Character || !Character->IsValidLowLevel())
{
return;
}
FCollisionQueryParams CollisionParams;
CollisionParams.AddIgnoredActor(Character);
CollisionParams.AddIgnoredComponent(Character->GetCapsuleComponent());
CollisionParams.bReturnPhysicalMaterial = true;
FVector StartPos = MeshComp->GetOwner()->GetActorLocation();
FVector EndPos = StartPos;
EndPos.Z -= 300.f;
double Length = Character->GetVelocity().Length();
// 달리기 or 걷기 속도에 따른 발소리 볼륨값 조절
double OutValue = UKismetMathLibrary::MapRangeClamped(Length, 200.0, 600.0, 0.0, 1.0);
// 마스터볼륨 조절
double StepSoundM = 0.5;
OutValue *= StepSoundM;
FHitResult HitResult;
// 바닥으로 Lay를 쏴 피직스 메테리얼을 판단후 해당 Step Sound를 출력하도록 구현
if (Character->GetWorld()->LineTraceSingleByChannel(HitResult, StartPos, EndPos,
ECollisionChannel::ECC_Visibility, CollisionParams))
{
m_StepSurface = UGameplayStatics::GetSurfaceType(HitResult);
if (!m_StepSurface)
{
UE_LOG(LogTemp, Error, TEXT("FootStep Surface Null!"));
}
Sound = SelectSoundBase();
if (Sound == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("FootStep Sound Null!"));
return;
}
VolumeMultiplier = OutValue;
Super::Notify(MeshComp, Animation, EventReference);
}
}
cs에 AI모듈 추가해야 한다.
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class Blaster : ModuleRules
{
public Blaster(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "AIModule" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
영상
https://youtu.be/F3p1mF8w6Hc
반응형
'언리얼5' 카테고리의 다른 글
[UE5 Multiplayer Shooting-11] Automatic Fire, CorsshiarHUD, Zoom 완성 (1) | 2023.08.11 |
---|---|
[UE5 Multiplayer Shooting-10] 반자동 라이플 발사, Crosshair 일부 (2) | 2023.08.08 |
[UE5 Multiplayer Shooting-8] 무기 HUD 표시 및 장착 | RPC (11) | 2023.08.02 |
[UE5 Multiplayer Shooting-7] Network Role에 관해 (1) | 2023.08.01 |
[UE5 Multiplayer Shooting-6] UE5 IK_Rig_Retargeting | IK 릭 리타겟팅 (2) | 2023.07.30 |
댓글