본문 바로가기
Study/Unreal

[Unreal/정리] 애니메이션 속도 제어

by generous_jeans 2020. 11. 17.

- 애니메이션 속도 제어 -

(언리얼 에디터-BPWukongAnim) 디테일 -> 세팅-Play Rate : 숫자로 애니메이션 속도를 조절할 수 있음, 

 

// 초당 공격 속도 계산.

(언리얼 에디터-BPWukongAnim) Attack마다 공격 길이 체크

 

(C++-WukongAnim.h)

...
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    bool AttackEnable;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    TArray<float> AttackRate;    
...

 

(C++-PlayerCharacter.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "GameFramework/Character.h"
#include "PlayerCharacter.generated.h"

USTRUCT(Atomic, BlueprintType)
struct FCharacterState
{
    GENERATED_USTRUCT_BODY()

public:
    FCharacterState()
    {
    }

public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    FString strName;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fAttack;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fArmor;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iHP;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iHPMax;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iMP;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iMPMax;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fAttackDist;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fAttackSpeed;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fMoveSpeed;
    
};
...

 

 

(언리얼 에디터-BPWukongAnim) 디테일 -> AttackRate 배열 추가하여 공격속도에 곱할 배율 입력

// ex. 공격 길이가 1.33이면 1.33 곱해서 1초로 설정,

 

(C++-PlayerCharater.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerCharacter.h"
#include "Weapon.h"
#include "MainHUDWidget.h"
#include "MainGameMode.h"
#include "HitCameraShake.h"

// Sets default values
APlayerCharacter::APlayerCharacter()
{
    // 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;

    bStartAnimation = false;

    GetMesh()->SetReceivesDecals(false);

    CharacterState.fAttackSpeed = 1.f;
    
}
...

 

(C++-WukongAnim.h)

...
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    bool AttackEnable;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    TArray<float> AttackRate;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float AttackSpeed;

    uint8 NextAttackMax;
    bool NextAttack;
    bool NextAttackEnable;
    bool NextAttackInputEnable;

public:
    void SetMoveDir(EDir eDir)
    {
        Dir = (uint8)eDir;
    }

    void SetAttackSpeed(float fSpeed)
    {
        AttackSpeed = fSpeed;
    }
...

 

(C++-WukongAnim.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "WukongAnim.h"
#include "Wukong.h"

UWukongAnim::UWukongAnim()
{
    Dir = (uint8)EDir::Front;

    MoveStop = true;
    AttackEnable = true;
    NextAttack = false;
    NextAttackInputEnable = false;
    NextAttackIndex = 0;
    NextAttackEnable = true;
    NextAttackMax = 5;
    AttackSpeed = 1.f;

    static ConstructorHelpers::FObjectFinder<UAnimMontage> Skill1Asset(TEXT("AnimMontage'/Game/Player/MTGWukongAttack.MTGWukongAttack'"));

    if (Skill1Asset.Succeeded())
        Skill1Montage = Skill1Asset.Object;
}
...

 

(C++-Wukong.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "Wukong.h"
#include "WukongAnim.h"
#include "Weapon.h"
#include "EffectDestroy.h"
#include "DrawDebugHelpers.h"

// Sets default values
AWukong::AWukong()
{
    // 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;

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Arm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Arm"));

    Arm->SetupAttachment(GetMesh());
    Camera->SetupAttachment(Arm);

    // 애니메이션 클래스 지정.
    static ConstructorHelpers::FClassFinder<UWukongAnim> AnimAsset(TEXT("AnimBlueprint'/Game/Player/BPWukongAnim.BPWukongAnim_C'"));

    if (AnimAsset.Succeeded())
        GetMesh()->SetAnimInstanceClass(AnimAsset.Class);

    Weapon = nullptr;

    GetCapsuleComponent()->SetCollisionProfileName(TEXT("Player"));

    WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponBox"));

    WeaponBox->SetupAttachment(GetMesh(), TEXT("FX_Staff_Mid"));

    WeaponBox->SetCollisionProfileName(TEXT("PlayerAttack"));

    WeaponBox->SetBoxExtent(FVector(120.f, 10.f, 10.f));

    static ConstructorHelpers::FClassFinder<AProjectileSkill> ProjectileAsset(TEXT("Blueprint'/Game/Skill/BPProjectileSkill.BPProjectileSkill_C'"));

    if (ProjectileAsset.Succeeded())
        ProjectileSkillClass = ProjectileAsset.Class;

    CharacterState.fAttack = 20.f;
    CharacterState.fArmor = 10.f;
    CharacterState.iHP = 500;
    CharacterState.iHPMax = 500;
    CharacterState.iMP = 100;
    CharacterState.iMPMax = 100;
    CharacterState.fAttackDist = 150.f;
    CharacterState.fAttackSpeed = 1.5f;
}

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

    WukongAnim = Cast<UWukongAnim>(GetMesh()->GetAnimInstance());

    WukongAnim->SetAttackSpeed(CharacterState.fAttackSpeed);  // AttackSpeed 설정. 

    // 기본 무기를 설정.
    FActorSpawnParameters params;
    params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;

    Weapon = GetWorld()->SpawnActor<AWeapon>(FVector::ZeroVector, FRotator::ZeroRotator, params);

    Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, TEXT("weapon_l_socket"));

    Weapon->LoadMesh(TEXT("SkeletalMesh'/Game/InfinityBladeWeapons/Weapons/Blade/Swords/Blade_BlackKnight/SK_Blade_BlackKnight.SK_Blade_BlackKnight'"));

    WeaponBox->OnComponentBeginOverlap.AddDynamic(this, &AWukong::WeaponBeginOverlap);
    WeaponBox->OnComponentEndOverlap.AddDynamic(this, &AWukong::WeaponEndOverlap);

    WeaponBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    
}
...

 

(언리얼 에디터-BPWukongAnim) Attack -> Attack1~5 이벤트 그래프

(언리얼 에디터-BPWukongAnim) Attack -> Attack1~5Recovery 이벤트 그래프

// 속도가 느려지는 것을 이용하여 일정 구역에 들어가면 속도가 느려지는 트리거를 제작할 수 있음.

 

(언리얼 에디터-BPWukongAnim) Attack -> Attack1~5 노티파이 위치 변경

 

// 공격속도가 변할 때마다 Set함수만 호출해주면 됨. 

 

// 이동속도가 빨라지면 모션속도도 빨라져야 함. 

 

 

댓글