• ACharactor 에 점프함수가 구현되어 있다.
  • 입력에 있는 점프와 바인딩을 한다.
AABCharacter::AABCharacter()
{
 ...

    ArmLengthSpeed = 3.0f;
    ArmRotationSpeed = 10.0f;
    GetCharacterMovement()->JumpZVelocity = 800.0f; 
}

void AABCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
...
    PlayerInputComponent->BindAction(TEXT("Jump"), EInputEvent::IE_Pressed, true, &AABCharacter::Jump);
}

  • 애니메이션블루프린트는 현재 캐릭터가 점프, 땅 위 인지 알 수 있어야 한다
  • 현재 움직임을 파악하기 위해 폰의 무브먼트 컴포넌트 함수 제공
  • IsFalling() : 공중에 떠 있는지
  • IsSwimming() : 현재 수영 중인지
  • IsCrouching() : 쭈구려 있는지
  • IsMoveOnGround() : 땅 위에서 이동 중인지
  • 폰의 점프 상황을 보관하기 위해 IsInAir 을 선언하고, 폰 무브먼트 컨포넌트 IsFalling() 함수를 호출해 두 값이 일치하도록 만든다.
class KGAME_API UABAnimInstance : public UAnimInstance
{
....
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
    bool IsInAir;
};
UABAnimInstance::UABAnimInstance()
{
    CurrentPawnSpeed = 0.0f;
    IsInAir = false;
}

void UABAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);
    auto Pawn = TryGetPawnOwner();
    if (::IsValid(Pawn))
    {
        CurrentPawnSpeed = Pawn->GetVelocity().Size();
        auto Character = Cast<ACharacter>(Pawn);
        if (Character)
        {
            IsInAir = Character->GetMovementComponent()->IsFalling();
        }
    }
}

 


애님블루프린트

 

 

BaseAction

 

  • 게임엔진은 틱마다 입력 시스템 > 게임로직 > 애니메이션 시스템순으로 로직을 실행한다.
  • 플레이어의 의지인 입력 값을 받은 후 그것을 해석해 폰을 움직이게 만들고, 폰의 최종 움직임과 맞는 애니메이션을 재생시키는 것이 자연스럽기 떄문이다.
  • 애니메이션에 앞서 폰을 제거 한다면, 애니메이션 로직은 더 이상 유효하지 않은 객체를 참조하게 된다
  • 그래서 폰 객체를 확인하는 함수 TryGetPawn()을 사용한다

NativeAnimationUpdate 함수

  • 애님인스턴스 클래스에서 매틱 마다 호출을 한다.
  • 호출은 되나, 타고가서 보면 내용은 아무 것도 없음
  • 이를 재정의해서 매 틱 호출

애니메이션에서 폰의 정보를 가져오서 속도를 적용

//cpp
class KGAME_API UABAnimInstance : public UAnimInstance
{
    GENERATED_BODY()

public:
    UABAnimInstance();
    virtual void NativeUpdateAnimation(float DeltaSeconds) override;
private:
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
    float CurrentPawnSpeed;

};
UABAnimInstance::UABAnimInstance()
{
    CurrentPawnSpeed = 0.0f;
}


void UABAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);
    auto Pawn = TryGetPawnOwner();                     
    if (::IsValid(Pawn))
    {
        CurrentPawnSpeed = Pawn->GetVelocity().Size();
    }

}

폰에서 애니메이션을 불러와 속도를 적용

//애님인스턴스.h
UCLASS()
class KGAME_API UABAnimInstance : public UAnimInstance
{
    GENERATED_BODY()

public:
    UABAnimInstance();
    virtual void NativeUpdateAnimation(float DeltaSeconds) override;
    void SetPawnSpeed(float NewPawnSPeed) { CurrentPawnSpeed = NewPawnSPeed; }
private:
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
    float CurrentPawnSpeed;
};
//캐릭터 cpp
void AABCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

 . . .

    auto ABInstance = Cast<UABAnimInstance>(GetMesh()->GetAnimInstance());
    if (ABInstance != nullptr)
    {
        ABInstance->SetPawnSpeed(GetVelocity().Size());
    }
}

'Unreal > Game 1 (C++)' 카테고리의 다른 글

9.애니메이션 몽타주  (1) 2019.05.02
8.점프구현 / 캐릭터 상태체크  (0) 2019.05.02
6.3인칭 컨트롤 구현 (디아블로방식)  (0) 2019.05.02
6.3인칭 컨트롤 구현 (GTA 방식)  (0) 2019.05.02
5.캐릭터 생성  (0) 2019.05.02
  1. 캐릭터 이동 : 보는 시점에서 상하좌우 방향으로 마네킹이 이동
  2. 캐릭터 회전 : 캐릭터가 이동하는 방향으로 마네킹이 회전
  3. 지지대 : 450m
  4. 카메라 회전 : 마우스 상하좌우 이동에 따라 카메라 지지대가 상화좌우로 회전
  5. 카메라 줌 : 카메라 시선과 캐릭터 사이에 장애물이 감지 되면 캐릭터가 보이도록 카메라를 장애물 앞으로 줌인
case EControlMode::DIABLO: 
//SpringArm->TargetArmLength = 800.0f; 
//SpringArm->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); 
ArmLengthTo = 800.0f; 
ArmRotationTo = FRotator(-45.0f, 0.0f, 0.0f); 
SpringArm->bUsePawnControlRotation = false; 
SpringArm->bInheritPitch = false; 
SpringArm->bInheritRoll = false; 
SpringArm->bInheritYaw = false; 
SpringArm->bDoCollisionTest = false; 
bUseControllerRotationYaw = false; 
GetCharacterMovement()->bOrientRotationToMovement = false; 
GetCharacterMovement()->bUseControllerDesiredRotation = true; 
GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);

'Unreal > Game 1 (C++)' 카테고리의 다른 글

8.점프구현 / 캐릭터 상태체크  (0) 2019.05.02
7.애니메이션 폰과 데이터 연동  (0) 2019.05.02
6.3인칭 컨트롤 구현 (GTA 방식)  (0) 2019.05.02
5.캐릭터 생성  (0) 2019.05.02
4.애니메이션 재생  (0) 2019.05.02
  1. 캐릭터 이동 : 보는 시점에서 상하좌우 방향으로 마네킹이 이동
  2. 캐릭터 회전 : 캐릭터가 이동하는 방향으로 마네킹이 회전
  3. 지지대 : 450m
  4. 카메라 회전 : 마우스 상하좌우 이동에 따라 카메라 지지대가 상화좌우로 회전
  5. 카메라 줌 : 카메라 시선과 캐릭터 사이에 장애물이 감지 되면 캐릭터가 보이도록 카메라를 장애물 앞으로 줌인
void AABCharacter::UpDown(float axis)
{
    AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::X), axis););
}
void AABCharacter::RightLeft(float axis)
{
    AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::Y), axis););
}

void AABCharacter::Turn(float axis)
{
    AddControllerYawInput(axis);

}
void AABCharacter::LookUp(float axis)
{
    AddControllerPitchInput(axis);
}

void AABCharacter::SetControlMode(int32 controlMode)
{
    if (controlMode == 0)
    {
        SpringArm->TargetArmLength = 450.0f;
        SpringArm->SetRelativeRotation(FRotator::ZeroRotator);
        SpringArm->bUsePawnControlRotation = true;
        SpringArm->bInheritPitch = true;
        SpringArm->bInheritRoll = true;
        SpringArm->bInheritYaw = true;
        SpringArm->bDoCollisionTest = true;
        bUseControllerRotationYaw = false;
        GetCharacterMovement()->bOrientRotationToMovement = true;
        GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
    }
}

'Unreal > Game 1 (C++)' 카테고리의 다른 글

7.애니메이션 폰과 데이터 연동  (0) 2019.05.02
6.3인칭 컨트롤 구현 (디아블로방식)  (0) 2019.05.02
5.캐릭터 생성  (0) 2019.05.02
4.애니메이션 재생  (0) 2019.05.02
3.에디터 - 폰 입력 연동, 바인딩  (0) 2019.05.02
  • ACharactor 상속을 타고 가면 APawn 이 있다
  • 캡술과 메쉬는 겟터함수를 이용해서 사용한다.
  • GetMesh(), GetCapsuleComponent
  • 그것 뺴곤 폰하고 일치
UCLASS(config=Game, BlueprintType, meta=(ShortTooltip="A character is a type of Pawn that includes the ability to walk around."))
class ENGINE_API ACharacter : public APawn
{
    GENERATED_BODY()
public:
    /** Default UObject constructor. */
    ACharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

    void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

private:
    /** The main skeletal mesh associated with this Character (optional sub-object). */
    UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
    USkeletalMeshComponent* Mesh;

    /** Movement component used for movement logic in various movement modes (walking, falling, etc), containing relevant settings and functions to control movement. */
    UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
    UCharacterMovementComponent* CharacterMovement;

    /** The CapsuleComponent being used for movement collision (by CharacterMovement). Always treated as being vertically aligned in simple collision check functions. */
    UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
    UCapsuleComponent* CapsuleComponent;

AABCharacter::AABCharacter()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SPRINGARM"));
    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("CAMERA"));

    SpringArm->SetupAttachment(GetCapsuleComponent());
    Camera->SetupAttachment(SpringArm);


    GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -88.0f), FRotator(0.0f, -90.0f, 0.0f));
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->SetRelativeRotation(FRotator(-15.0f, 0.0f, 0.0f));

    static ConstructorHelpers::FObjectFinder<USkeletalMesh>
        SK_CARDBOARD(TEXT("/Game/InfinityBladeWarriors/Character/CompleteCharacters/SK_CharM_Cardboard.SK_CharM_Cardboard"));

    if (SK_CARDBOARD.Succeeded())
    {
        GetMesh()->SetSkeletalMesh(SK_CARDBOARD.Object);
    }


    GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint);
    static ConstructorHelpers::FClassFinder<UAnimInstance>  WARRIOR_ANIM(TEXT("/Game/Book/ANIM/WarriorAnimBluePrint.WarriorAnimBluePrint_C"));

    if (WARRIOR_ANIM.Succeeded())
    {
        GetMesh()->SetAnimInstanceClass(WARRIOR_ANIM.Class);
    }

}

// Called when the game starts or when spawned
void AABCharacter::BeginPlay()
{
    Super::BeginPlay();

}

// Called every frame
void AABCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AABCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAxis(TEXT("UpDown"),this, &AABCharacter::UpDown);
    PlayerInputComponent->BindAxis(TEXT("RightLeft"), this, &AABCharacter::RightLeft);
    PlayerInputComponent->BindAxis(TEXT("Turn"), this, &AABCharacter::Turn);
    PlayerInputComponent->BindAxis(TEXT("LookUp"), this, &AABCharacter::LookUp);
}

void AABCharacter::UpDown(float axis)
{
    AddMovementInput(GetActorForwardVector(), axis);
}
void AABCharacter::RightLeft(float axis)
{
    AddMovementInput(GetActorRightVector(), axis);
}


void AABCharacter::Turn(float axis)
{
    AddControllerPitchInput(axis);
}
void AABCharacter::LookUp(float axis)
{
    AddControllerYawInput(axis);
}

 

+ Recent posts