UE4(BP & C++) FootIK ์ ์šฉ


Tags : FootIK IKComponent Footstep UStruct Animation


IKComponent๋ฅผ ํ†ตํ•ด Character์˜ ๋ฐœ๋ฐ”๋‹ฅ๊ณผ ์ง€ํ˜•์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋งž๋‹ฟ์„ ์ˆ˜ ์žˆ๋„๋ก FootIK ์ ์šฉํ•˜๊ธฐ

DiffIK

์š”์•ฝ

  • ์ฃผ์š” ๋ชฉํ‘œ : ์ง€ํ˜•๊ณผ ์–ด์šฐ๋Ÿฌ์ง€๋Š” ์›€์ง์ž„์„ ์œ„ํ•ด FootIK ์ ์šฉํ•˜๊ธฐ
  • ๐Ÿ’ซ๋ฐœ์ƒ ๋ฌธ์ œ : Skeletal Mesh์˜ Scale์„ ์กฐ์œจํ•œ ๊ฒฝ์šฐ Foot Effecter๊ฐ’์— ์˜ค์ฐจ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ ๋ฐฉ์•ˆ :
    1. Skeletal Mesh์˜ Foot๋ณธ์— ์ถ”๊ฐ€ํ•œ Socket์—์„œ๋ถ€ํ„ฐ ์ง€๋ฉด์„ ํ–ฅํ•œ ์‹ค์‹œ๊ฐ„ ์ˆ˜์ง Line Trace๋กœ ์ง€๋ฉด๊ณผ Foot์˜ ์œ„์น˜์™€ ๊ฐ๋„ ์ฐจ์ด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ABP์—์„œ Bone Transform๊ณผ 2 Bone IKํ•จ์ˆ˜๋กœ ํ•˜์ฒด ์ฃผ์š” Bone์— ์ ์šฉ
    2. OwnerCharacter๋กœ๋ถ€ํ„ฐ GetActorScale์˜ Z๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›์•„ ๊ฐ Foot Effector์— ๋‚˜๋ˆ„๊ธฐ
  • ์ด๋ฃจ์–ด๋‚ธ ์„ฑ๊ณผ :
    1. ๊ฐ๊ธฐ ๋‹ค๋ฅธ Skeletal Mesh์™€ Scale ๊ตฌ์„ฑ์— ๋”ฐ๋ฅธ ์˜ค์ฐจ์—๋„ ์ผ๊ด„ ์ ์šฉ๊ฐ€๋Šฅํ•œ IKComponent ๊ตฌํ˜„
    2. ๊ณ„๋‹จ ๋˜๋Š” ๊ตด๊ณก์žˆ๋Š” ์ง€ํ˜•์— ์ž˜ ์–ด์šฐ๋Ÿฌ์ง€๋Š” ์›€์ง์ž„ ๊ตฌํ˜„
    3. Bone Transform๊ณผ 2 Bone IK์— ๋Œ€ํ•œ ์ดํ•ด

Abstract

  • Line Trace์˜ ์‹œ์ž‘์ ์€ Socket์˜ ์œ„์น˜์ง€๋งŒ, ์‹ค์ œ Skeletal Mesh์˜ Foot ๋ณธ์˜ ์œ„์น˜๊ฐ€ ์•„๋‹Œ ๋ฐœ๋ฐ”๋‹ฅ๋ฉด์˜ ์œ„์น˜์ธ Mesh์˜ Location๊ณผ Hit๋œ Impact Point ๊ฐ„ ๊ฑฐ๋ฆฌ ์ธก์ •
    ํ•˜์ดํž์„ ์‹ ์—ˆ๊ฑฐ๋‚˜ ๋ฐœ๊ฟˆ์น˜๊ฐ€ ๋‚ฉ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ Mesh์—๋„ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค
  • ๋ฐ”๋‹ฅ๊ณผ ๋†’์ด์ฐจ๊ฐ€ ๋” ํฐ ๊ฐ’ ๋งŒํผ Pelvis๋ฅผ ๋‚ด๋ ค ์ƒ๋Œ€์ ์œผ๋กœ ์œ„์— ์œ„์น˜ํ•œ ๋‹ค๋ฆฌ์—๋งŒ ๋ณ€ํ˜•์„ ์ค€๋‹ค Skeletal Mesh์˜ Pelvis ์œ„์น˜, ํ•˜์ฒด ๊ธธ์ด ๋น„์œจ ๋“ฑ ๋ณ€์ˆ˜์— ์˜ํ–ฅ์ด ์—†๋‹ค

Rotation

  • LineTrace Hit๋œ ์ง€๋ฉด์˜ Normal๋ฒกํ„ฐ๋ฅผ ํ†ตํ•ด ์ง€๋ฉด์ด ๊ธฐ์šธ์–ด์ง„ ์ •๋„๋ฅผ atan2๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์ง€๋ฉด์˜ ๊ธฐ์šธ๊ธฐ๋กœ ๋ฐœ๋ชฉ์˜ Yaw ํšŒ์ „์ด ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ๋Š” ์ ์–ด ์ƒ๋žตํ•˜๊ณ  Roll, PitchํšŒ์ „ ๊ฐ’์— ์ ์šฉ



Settings

  1. Bone Transform์— ์˜ํ•ด ๋ณ€๋™๋˜์ง€ ์•Š์„ ๊ณ ์ •๊ฐ’์„ ์œ„ํ•ด ๊ฐ Foot๋ณธ์— ์†Œ์ผ“ ์ถ”๊ฐ€
  2. IK์ •๋ณด๋ฅผ ๋‹ด์•„ ABP์— ์ „๋‹ฌํ•ด์ค„ ๊ตฌ์กฐ์ฒด FootIKData ์ƒ์„ฑ

    ๊ตฌ๋ถ„ ์ด๋ฆ„ ๋‚ด์šฉ
    float DisplacementZ Pelvis์— ์ ์šฉํ•  Location.Z
    vector IKEffector_L
    IKEffector_R
    Foot_L๋˜๋Š” Foot_R์— Effector Location์œผ๋กœ ์ ์šฉ๋  ๋ฒกํ„ฐ
    rotator Rot_L
    Rot_R
    Foot_L ๋˜๋Š” Foot_R์— ์ ์šฉํ•  Rotator๊ฐ’
  3. IKComponent ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ -> ์บ๋ฆญํ„ฐ์— ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€



Blueprint IKComponent

FootIK์˜ ๊ฐœ๋…๊ณผ ๊ตฌํ˜„๋ฐฉ๋ฒ•์€ ๊ด€๋ จ Unreal Engine Documentation 1 ์™€ Ryan Laley์˜ YouTube ์ฑ„๋„ IK์‹œ๋ฆฌ์ฆˆ 2 ๋ฅผ ์ฐธ๊ณ ํ–ˆ๊ณ , ์‚ฌ์šฉํ•˜๋Š” Mannequin์˜ height ๋“ฑ Mesh Asset์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ธํ•œ ์˜ค์ฐจ๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉํ–ˆ๋‹ค
image

์บ๋ฆญํ„ฐ๊ฐ€ ์ ํ”„๋‚˜ ๊ณต์ค‘์— ๋– ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ์•„๋‹Œ๊ฒฝ์šฐ์—๋งŒ FootIK๊ฐ€ ์ ์šฉ๋˜๋„๋ก Branch๋ฅผ ๊ฑธ์–ด์ค€ ๋’ค SetIKํ•จ์ˆ˜๋ฅผ Tick๋งˆ๋‹ค ํ˜ธ์ถœ

  • Variables

    ๊ตฌ๋ถ„ ์ด๋ฆ„ ๋‚ด์šฉ
    Character OwnerCharacter IKComponent๋ฅผ ์†Œ์œ ํ•œ ์บ๋ฆญํ„ฐ ์•กํ„ฐ
    (struct)FootIKData FootIKData IKComponent์—์„œ ๊ณ„์‚ฐ ์™„๋ฃŒ๋˜์–ด ABP๋กœ ์ „๋‹ฌํ•ด ์ค„ Transform ๋ฐ์ดํ„ฐ
    float Displacement FootIKData.DisplacementZ์— set ๋  Pelvis๊ฐ€ Z์ด๋™ํ•ด์•ผ ํ•  ๊ฐ’
    float LFootEffector
    RFootEffector
    FootIKData.IKEffector_L.X ๋˜๋Š” FootIKData.IKEffector_R.X์— set ๋ 
    Foot_L๊ณผ ์ง€๋ฉด์˜ ๋†’์ด ์ฐจ(์œ„์•„๋ž˜๊ฐ€ ๋’ค์ง‘์–ด์ง„ Foot_R๋ณธ์œผ๋กœ ์ธํ•ด * -1.0f)
    rotator LFootRotator
    RFootRotator
    FootIKData.Rot_L ๋˜๋Š” FootIKData.Rot_R์— set๋  ์ง€๋ฉด ๋…ธ๋ง๋ฒกํ„ฐ์˜ ์—ญ๊ฐ
    float CharacterScale Scale์ ์šฉ์œผ๋กœ ์ธํ•œ ์˜ค์ฐจ๊ณ„์‚ฐ์šฉ OwnerCharacter์˜ ActorWorldScale3D.Z
  • Functions

    ์ด๋ฆ„ ๋‚ด์šฉ
    LineTrace ์ž…๋ ฅ๋ฐ›๋Š” socket์ด๋ฆ„์—์„œ๋ถ€ํ„ฐ ์ง€๋ฉด์„ ํ–ฅํ•ด ์ˆ˜์ง Line Trace ํ•œ ๋’ค
    Hit๋œ ์ง€์ ์˜ Impact Point์™€ Normal๋กœ ๋ฐœ์˜ ์œ„์น˜์™€ ์ง€๋ฉด์˜ ๊ฑฐ๋ฆฌ, ์—ญ๊ฐ์„ ๋ฐ˜ํ™˜ํ•ด์ค„ ํ•จ์ˆ˜
    SetIK Tick๋งˆ๋‹ค ์–‘ ๋ฐœ์˜ LineTrace๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ FootIKData๋ฅผ Setํ•ด์ฃผ๋Š” ํ•จ์ˆ˜


LineTrace

  • Input
    • InSocketName : LineTrace๋ฅผ ์‹œ์ž‘ํ•  Socket์˜ ์ด๋ฆ„
  • Return
    • FootTraceZ : Socket๊ณผ ์ง€๋ฉด์˜ ๊ฑฐ๋ฆฌ(๋†’์ด) ์ฐจ์ด
    • FootRot : ๋งž๋‹ฟ์€ ์ง€๋ฉด์˜ Normal Vector๋ฅผ ์—ญ๊ฐ์œผ๋กœ ๊ณ„์‚ฐํ•œ Rotation๊ฐ’

*Fullscreen๋˜๋Š” Ctrl+๋งˆ์šฐ์Šคํœ ๋กœ ZoomIn/Out ๊ฐ€๋Šฅ

  1. Foot_IK๋ณธ์˜ Location๋ฅผ Line Trace์˜ Start์ง€์ ์œผ๋กœ, End์ง€์ ์€ Foot_IK์˜ X,Y ๊ฐ’๊ณผ ํ•˜๋‹จ์ˆ˜์ง๋ฐฉํ–ฅ์ธ OwnerCharacter์˜ Mesh์˜ Z + Max Step Height๋กœ Set
    • Max Step Height๋ฅผ ์ ์šฉํ•œ ์ด์œ ๋Š” ์บ๋ฆญํ„ฐ๊ฐ€ ์ ํ”„์—†์ด ์˜ค๋ฅด๊ฑฐ๋‚˜ ์ถ”๋ฝ์ด ์•„๋‹Œ ๊ฑธ์Œ์œผ๋กœ ๋‚ด๋ ค๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋†’์ด๊นŒ์ง€๋งŒ ๋ฐœ์„ ์˜ฌ๋ฆฌ๊ฑฐ๋‚˜ ๋‚ด๋ฆฌ๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค
  2. Hit๊ฐ€ false์ผ ๋• ์ดˆ๊ธฐ๊ฐ’(0) ๋ฐ˜ํ™˜
  3. Hit๋œ Impact Point๋ฒกํ„ฐ์—์„œ ์บ๋ฆญํ„ฐ Mesh์˜ ์œ„์น˜๊นŒ์ง€ ๊ฑฐ๋ฆฌ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•œ ๋’ค Height๊ฐ€ ๋  Z๊ฐ’์„ FootTraceZ๋กœ ๋ฐ˜ํ™˜
  4. Hit๋œ Normal๋ฒกํ„ฐ๋ฅผ ์—ญ๊ฐ์œผ๋กœ ๊ณ„์‚ฐํ•ด์ฃผ๊ธฐ์œ„ํ•ด atan2๋กœ Pitch์™€ Roll๊ฐ’ ์‚ฐ์ถœ


SetIK

  • Input
    • InDeltaTime : Tickํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜๋ฐ›๋Š” DeltaSeconds ์ „๋‹ฌ

*Fullscreen๋˜๋Š” Ctrl+๋งˆ์šฐ์Šคํœ ๋กœ ZoomIn/Out ๊ฐ€๋Šฅ

  1. ๊ฐ ๋ฐœ์˜ IK๊ณ„์‚ฐ์„ ์œ„ํ•ด ์ถ”๊ฐ€ํ•œ Socket์„ ์ธ์ž๋กœ LineTrace ๋ฐœ๋งˆ๋‹ค ํ˜ธ์ถœ
  2. LineTrace๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์€ FootTraceZ๊ฐ’์„ ํ•ด๋‹น ๋ฐœ์˜ FootEffector์— Set
  3. ๊ฐ‘์ž‘์Šค๋Ÿฐ ์œ„์น˜์ ์šฉ์ด ์–ด์ƒ‰ํ•  ์ˆ˜ ์žˆ์–ด(โ€˜๋œฌ!โ€™ํ•˜๊ณ  ๋ˆˆ๊นœ์ง ํ•  ์‚ฌ์ด์— ๋ฐ”๋€Œ์–ด ์žˆ๋Š” ์œ„์น˜) FInterp์œผ๋กœ ๋ณด๊ฐ„ ์ ์šฉ
  4. LineTrace๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์€ FootRot๊ฐ’์„ ํ•ด๋‹น ๋ฐœ์˜ FootRotation์— RInterp์œผ๋กœ Set
  5. ๊ฐ Interp speed๋Š” ๋Ÿฐํƒ€์ž„ ํ™•์ธ ํ›„ 10.0f๊ฐ€ ๊ฐ€์žฅ ์ ์ ˆํ•˜์—ฌ ์ƒ์ˆ˜ Set
  6. LFootEffector์™€ RFootEffector์˜ ์ ˆ๋Œ€๊ฐ’ ์ค‘ ๋” ํฐ ๊ฐ’ ๋งŒํผ Pelvis๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ Displacement์— FInterp Set
  7. FootIKData.DisplacementZ์— Displacement๋ฅผ * -1.0f ํ•ด์„œ Set : Pelvis๋ฅผ ๋‚ด๋ ค์ค€๋‹ค
  8. FootIKData.IKEffector_L.X์— ๋‚ด๋ ค์ค€ Pelvis๋งŒํผ ๋” ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด LFootEffector์— Displacement๋ฅผ ๋บŒ
  9. FootIKData.IKEffector_R.X์—๋„ RFootEffector์—์„œ Displacement๋ฅผ ๋นผ์ค€ ๋’ค ๋’ค์ง‘์–ด์ง„ Foot_R์˜ X์ถ•์— ๋งž๊ฒŒ * -1.0f
  10. Scale์ด ํฌ๊ฑฐ๋‚˜ ์ž‘์€ Skeletal Mesh์˜ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด CharacterScale๊ฐ’์„ ๊ฐ ๋ฐœ์— ๋‚˜๋ˆ ์คŒ
    • Scale์ด ์ปค์ง„ ๊ฒฝ์šฐ ํ•ด๋‹น Scale๋งŒํผ ๋ฐœ๊ณผ ์ง€๋ฉด์˜ WorldSpace์ƒ์—์„œ์˜ ๊ฑฐ๋ฆฌ์ฐจ๊ฐ€ ์ปค์ง€์ง€๋งŒ BoneSpace๋Š” Scale์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์œผ๋ฏ€๋กœ์„ ์—ญ์‚ฐํ•ด์ค€๋‹ค

Scale applied


C++ IKComponent

// CFootIKComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "CIKComponent.generated.h"

USTRUCT(BlueprintType)
struct FFootIKData
{
    GENERATED_BODY()
public:
    UPROPERTY(BlueprintReadOnly, Category = "FootIK")
        FVector IKEffector_L;
    UPROPERTY(BlueprintReadOnly, Category = "FootIK")
        FVector IKEffector_R;
    UPROPERTY(BlueprintReadOnly, Category = "FootIK")
        FVector DisplacementZ;
        
    UPROPERTY(BlueprintReadOnly, Category = "FootIK")
        FRotator Rot_L;
    UPROPERTY(BlueprintReadOnly, Category = "FootIK")
        FRotator Rot_R;
};

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UE4_TPSProject UCIKComponent : public UActorComponent
{
    GENERATED_BODY()
public:
    UCIKComponent();
protected:
    virtual void BeginPlay() override;
public:	
    virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

private:    // Functions
    void LineTrace(FName InSocketName, float& OutFootTraceZ, FRotator& OutFootRot);

public:     // Inline
    FORCEINLINE FFootIKData GetData() { return FootIKData; }

private:    // UProperty Members
    UPROPERTY(EditAnywhere, Category = "LineTrace")
        TEnumAsByte<EDrawDebugTrace::Type> DrawDebug;
    UPROPERTY(EditAnywhere, Category = "LineTrace")
        float Displacement = 0.0f;
    UPROPERTY(EditAnywhere, Category = "LineTrace")
        float LFootEffector = 50.0f;
    UPROPERTY(EditAnywhere, Category = "TraLineTracece")
        float RFootEffector = 5.0f;
    UPROPERTY(EditAnywhere, Category = "LineTrace")
        FName LeftSocketName = "Foot_L_IK";
    UPROPERTY(EditAnywhere, Category = "LineTrace")
        FName RightSocketName = "Foot_R_IK";

private:    // Private Members
    class ACharacter* OwnerCharacter;
    FFootIKData FootIKData;
    float InterpSpeed = 10.0f;
    float CharacterScale = 1.0f;
};
// CFootIKComponent.cpp
#include "02_Components/CFootIKComponent.h"
#include "Global.h" // Utilities
#include "GameFramework/Character.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/CapsuleComponent.h"

#define LOG_UCFootIKComponent   // Debug Log

UCFootIKComponent::UCFootIKComponent()
{
    PrimaryComponentTick.bCanEverTick = true;
}

void UCFootIKComponent::BeginPlay()
{
    Super::BeginPlay();
    OwnerCharacter = Cast<ACharacter>(GetOwner());
}


LineTrace

// CFootIKComponent.cpp
void UCFootIKComponent::LineTrace(FName InSocketName, float& OutFootTraceZ, FRotator& OutFootRot)
{
    // Trace Start
    FVector start = OwnerCharacter->GetMesh()->GetSocketLocation(InSocketName);

    // Trace End
    FVector meshLocation = OwnerCharacter->GetMesh()->GetWorldLocation();
    float z = meshLocation.Z - OwnerCharacter->GetCharacterMovementComponent().MaxStepHeight;
    FVector end = FVector(socketLocation.X, socketLocation.Y, z);

    // LineTrace
    TArray<AActor*> ignores;
    ignores.Add(OwnerCharacter);
    FHitResult hitResult;
    
    UKismetSystemLibrary::LineTraceSingle(GetWorld(), start, end, ETraceTypeQuery::TraceTypeQuery1, true, ignores, DrawDebug, hitResult, true,FLinearColor::Green, FLinearColor::Red);
    
    // Init Outputs
    OutFootTraceZ = 0.0f;
    OutFootRot = FRotator::ZeroRotator;
    
    // Check Validity
    CheckFalse(hitResult.bBlockingHit);
    
    // OutFootTraceZ
    FVector distance = (hitResult.ImpactPoint - OwnerCharacter->GetMesh()->GetWorldLocation());
    OutFootTraceZ = distance.Z;

    // OutFootRot
    float roll = UKismetMathLibrary::DegAtan2(hitResult.Normal.Y, hitResult.Normal.Z);
    float pitch = UKismetMathLibrary::DegAtan2(hitResult.Normal.X, hitResult.Normal.Z) * -1.0f;	// -1 to Rotate in opposite direction
    OutRotation = FRotator(pitch, 0, roll);
}


Tick(SetIK)

// CFootIKComponent.cpp
void UCFootIKComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    
    // Check isFalling
    CheckFalse(OwnerCharacter->GetCharacterMovementComponent()->IsFalling());

    // Temp Variables
    float leftTrace = 0.0f;
    float rightTrace = 0.0f;
    float displacement = 0.0f;
    FRotator leftRot;
    FRotator rightRot;

    // Character Scale Check
    CharacterScale = OwnerCharacter->GetActorWorldScale3D().Z;
    
    // LineTrace from both Sockets
    LineTrace(LeftSocketName, leftTrace, leftRot);
    LineTrace(RightSocketName, rightTrace, rightRot);

    // Pelvis
    displacement = FMath::Max(Abs(leftTrace), Abs(rightTrace));
    
    FootIKData.DisplacementZ.Z = UKismetMathLibrary::FInterpTo(FootIKData.DisplacementZ.Z, displacement, DeltaTime, InterpSpeed);
    
    // Left Foot
    FootIKData.IKEffector_L.X = UKismetMathLibrary::FInterpTo(FootIKData.IKEffector_L.X, (leftTrace-displacement) / CharacterScale, DeltaTime, InterpSpeed);
    FootIKData.Rot_L = UKismetMathLibrary::RInterpTo(FootIKData.Rot_L, leftRot, DeltaTime, InterpSpeed);
    
    // Right Foot
    FootIKData.IKEffector_R.X = UKismetMathLibrary::FInterpTo(FootIKData.IKEffector_R.X, -(rightTrace-displacement) / CharacterScale, DeltaTime, InterpSpeed); // -rightTrace due to opposite bone direction
    FootIKData.Rot_R = UKismetMathLibrary::RInterpTo(FootIKData.Rot_R, rightRot, DeltaTime, InterpSpeed);
    

#ifdef  LOG_UCFootIKComponent
	CLog::Print(FootIKData.DisplacementZ, 11);
	CLog::Print(FootIKData.IKEffector_L, 12);
	CLog::Print(FootIKData.Rot_L, 13);
	CLog::Print(FootIKData.IKEffector_R, 14);
	CLog::Print(FootIKData.Rot_R, 15);
#endif // LOG_UCFootIKComponent
}

Animation Blueprint

  • Variables
    • component IKComp : OwnerCharacter๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜จ IKComponent ๋ณ€์ˆ˜๋กœ Set
    • (struct)FootIKData FootIKData : IKComp๊ฐ€ ์œ ํšจํ•  ๊ฒฝ์šฐ Getter๋กœ ๊ฐ€์ ธ์™€ ๋ณ€์ˆ˜๋กœ Set
    • bool IKSpace : IK ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ ์ฒดํฌ๋ฅผ ์œ„ํ•œ bool
      ex) Player์˜ ๊ฒฝ์šฐ Parkour ์ง„ํ–‰ ์‹œ IK ์ ์šฉํ•ด์ œ
  • Animation Layer
    1. ์ตœ์ข… ์• ๋‹ˆ๋ฉ”์ด์…˜ ํฌ์ฆˆ ๋ฐ˜ํ™˜ ์ง์ „ IKLayer ๋งํฌ
    2. IKSpace์˜ ๊ฐ’์— ๋”ฐ๋ผ bool๋กœ ํฌ์ฆˆ๋ธ”๋žœ๋”ฉ

SetUpBasicData

image

BlueprintUpdateAnimationEvent๋ฅผ ํ†ตํ•ด Update๋งˆ๋‹ค OwnerCharacter์˜ IKComponent๋ฅผ ํ†ตํ•ด FootIKData๋ฅผ Setํ•ด์ฃผ๊ณ  ์บ๋ฆญํ„ฐ์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ์œ ํšจ์„ฑ ํ™•์ธ์„ ์œ„ํ•ด bool IKSpace ์ฒดํฌ


IKLayer

image image

์ž…๋ ฅ๋ฐ›์€ ํฌ์ฆˆ์˜ ๋ณธ์— ๋ณ€ํ˜•์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ Space๋กœ ์ „ํ™˜ํ•ด Bone Transform๊ณผ 2 Bone IKํ•จ์ˆ˜๋กœ IK ์ ์šฉ๋œ ํฌ์ฆˆ ๊ตฌํ˜„

  • Pelvis Bone Transform :
    Translation ๊ธฐ์กด ์œ„์น˜์—์„œ WorldSpace๊ธฐ์ค€ FootIKData.DisplacementZ Add to Existing
  • Foot_L
    1. 2 Bone IK :
      Effector Location - Foot_L ๋ณธ์˜ ๊ธฐ์กด ์œ„์น˜์—์„œ BoneSpace๊ธฐ์ค€ FootIKData.IKEffector_L ์ž…๋ ฅ
      Joit Target Location - Calf_L ๋ณธ์˜ ๊ธฐ์กด ์œ„์น˜์—์„œ ์‚ด์ง ์•ž์œผ๋กœ ํ–ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ BoneSpace๊ธฐ์ค€์œผ๋กœ ์ ์šฉ
      ๋Ÿฐํƒ€์ž„์œผ๋กœ ํ™•์ธ ํ›„ X=0.0, Y=30.0, Z=-5.0 ์ •๋„๊ฐ€ ์ ์ ˆํ•˜์—ฌ ์ ์šฉ
    2. Bone Transform :
      Rotation ๊ธฐ์กด ํšŒ์ „๊ฐ’์—์„œ WorldSpace๊ธฐ์ค€ FootIKData.Rot_L Add to Existing
  • Foot_R
    Foot_L๊ณผ ๋™์ผํ•˜๊ฒŒ ํ•ด๋‹นํ•˜๋Š” ๋ณธ์— FootIKData์˜ ์ •๋ณด ์ ์šฉ
    2 Bone IKํ•จ์ˆ˜ Joint Target Location์˜ Calf_R๋Š” ๋ฐ˜๋Œ€์ชฝ ๋‹ค๋ฆฌ์™€ ์ƒ๋ฐ˜๋œ ์ถ•์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด X=0.0, Y=-30.0, Z=5.0 ์ •๋„๊ฐ€ ์ ์ ˆ

์ƒ๊ฐ์ •๋ฆฌ

๊ธฐ๋ณธ์— ์ถฉ์‹คํ•˜๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌด๋ฃŒ๋กœ ์ œ๊ณต๋˜๋Š” ํ›Œ๋ฅญํ•œ IK Plugin๋“ค์ด ์žˆ์œผ๋‚˜ ์—ญ์‹œ๋‚˜ ๋ฐœ๋™ํ•œ ๊ฐœ๋ฐœ์š•์‹ฌ์— ํ•˜๋‚˜ํ•˜๋‚˜ ๋งŒ์ ธ๋ณด๊ณ  ๊ฒฐ๊ตญ ์›ํ•˜๋Š” ๋ชจ์Šต์„ ๊ตฌํ˜„ํ•ด ๋ฟŒ๋“ฏํ•˜๋‹ค
FootIK๋ฅผ ์ ์šฉํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ Tutorial๋“ค์„ ๋ณด์•˜์œผ๋‚˜,
์–ธ๋ฆฌ์–ผ์—”์ง„์˜ ๋””ํดํŠธ 3rd Person Character ๋˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ ์šฉํ•œ ํŠน์ • Skeletal Mesh ๊ฒฝ์šฐ์— ์ ์šฉ๋œ Foot IK๋กœ ํ‚ค ์ฐจ์ด ๋“ฑ์˜ offset์„ ์ƒ์ˆ˜๋กœ ์ ์šฉํ•˜๋Š” ์ผ€์ด์Šค๋“ค ๋ฟ์ด์—ˆ๋‹ค
์บ๋ฆญํ„ฐ๋“ค์ด ๋ณ€์‹ ํ•˜๊ณ  Scale๋„ ๋ณ€ํ˜•๋˜๋„๋ก ์„ค์ •ํ•œ ๋‚ด ํ”„๋กœ์ ํŠธ์—์„  ์ด๋Ÿฌํ•œ ์ƒ์ˆ˜๊ฐ’์„ ์ตœ๋Œ€ํ•œ ์ค„์ด๊ณ ์ž ๊ณ ๋ฏผ์„ ๋งŽ์ดํ–ˆ๋‹ค
๊ฒฐ๊ตญ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ๋‹ค์‹œ ์ •๋ฆฌํ•ด ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ •์—์„œ ์„ฑ๊ณตํ•˜๊ฒŒ ๋˜์—ˆ๊ณ  ์—ญ์‹œ ๊ธฐ๋ณธ๊ธฐ๊ฐ€ ํƒ„ํƒ„ํ•ด์•ผ ํ™œ์šฉ์— ๊ฐ•ํ•ด์งˆ ์ˆ˜ ์žˆ์Œ์„ ๋‹ค์‹œ๊ธˆ ๊นจ๋‹ซ๋Š” ์‹œ๊ฐ„์ด์—ˆ๋‹ค


Reference