모션워핑과 풀바디 IK: 상황에 대응하는 프로시저럴 애니메이션 제작하기 | 언리얼 서밋 2021
Constraint: 제약, 제한, 통제
IK 종류 |
---|
CCDIK (Cyclic Coordinate Descent Inverse Kinematics, 순환 좌표 하강 역운동학) |
Hand IK Retargeting |
Spline IK |
FABRIK |
Leg IK |
Two Bone IK |
Construction Script
IKTraceDistance는 스케일된 캐릭터 캡슐 절반 높이가 된다. 이 값은 캡슐 높이 또는 스케일이 변경되지 않는 이상 고정됨.
float Scale = GetActorTransform().GetScale3D().Z;
float IKTraceDistance = GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() * Scale;
IK Foot Trace
캡슐의 중심(대략적으로 캐릭터의 허리)에서 시작하여 캡슐 아래끝까지 line trace를 한다. bResult가 TRUE라는 것은 지면이 높아져서 지면과 충돌하는 경우다. 지면이 높으면 높을 수록 IKOffset의 값은 커질 것이다.
float ACharacter::IKFootTrace(float TraceDistance, FName Socket)
{
const FVector SocketLocation{ GetMesh()->GetSocketLocation(Socket) };
const FVector ActorLocation{ GetActorLocation() };
const FVector TraceStartLocation{ SocketLocation.X, SocketLocation.Y, ActorLocation.Z };
const FVector TraceEndLocation{ SocketLocation.X, SocketLocation.Y, ActorLocation.Z - TraceDistance };
FHitResult OutHit;
bool bResult = GetWorld()->LineTraceSingleByChannel(
OutHit,
TraceStartLocation,
TraceEndLocation,
ECollisionChannel::ECC_Visibility);
FVector Diff = TraceEndLocation - OutHit.Location;
float DiffSize = Diff.Size(); // 지면 높이와 TraceEndLocation의 차. 지면 높이가 높을 수록 차가 커짐.
return bResult ? DiffSize / Scale : 0.0f; // IKOffset 리턴
}
Event Tick
지면이 높아지면 높아진 만큼 발을 올려야 한다.
void ACharacterMaster::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
float IKOffset = IKFootTrace(IKTraceDistance, RightFootSocket);
IKOffsetRightFoot = UKismetMathLibrary::FInterpTo(IKOffsetRightFoot, IKOffset, DeltaTime, IKInterpSpeed);
IKOffset = IKFootTrace(IKTraceDistance, LeftFootSocket);
IKOffsetLeftFoot = UKismetMathLibrary::FInterpTo(IKOffsetLeftFoot, IKOffset, DeltaTime, IKInterpSpeed);
}
Event Graph - Event Blueprint Update Animation
Anim Graph