필요한 개념
<콤보>
콤보는 BP때와 알고리즘이 거의 동일하나, 몇가지 타격을 위해서만 좀 추가됨
ACDoAction_Melee 클래스의 DoAction(), Begin_DoAction(), End_DoAction()이 핵심
* 콤보를 위한 변수 세팅
// ACDoAction_Melee.h
FORCEINLINE void EnableCombo() { bEnable = true; }
FORCEINLINE void DisableCombo() { bEnable = false; }
bool bExist; // 다음 콤보가 존재하는지
bool bEnable; // 다음 콤보가 허용되었는지
bool bLast; // 콤보의 마지막인지
int32 Index; // 현재 몇번째 콤보중인지
// ACDoAction_Melee.cpp
void ACDoAction_Melee::DoAction()
{
Super::DoAction();
// 데이터 개수가 0보다 커야함
CheckFalse(Datas.Num() > 0);
// 다음콤보가 허용되었다면
if (bEnable == true)
{
// 다음콤보가 있다고 알려줌
bExist = true;
// 콤보 입력 더이상 하지 말라(이미 들어왔으니까)
bEnable = false;
return;
}
// IdleMode여야 함
CheckFalse(State->IsIdleMode());
State->SetActionMode();
const FDoActionData& data = Datas[0];
OwnerCharacter->PlayAnimMontage(data.AnimMontage, data.PlayRatio, data.StartSection);
data.bCanMove ? Status->SetMove() : Status->SetStop();
}
void ACDoAction_Melee::Begin_DoAction()
{
Super::Begin_DoAction();
CheckFalse(bExist);
bExist = false;
// 현재 플레이 중인 모든 몽타주를 중지시킴
// 이후에 Fist의 마지막 동작을 끊어서 사용하려고 넣은 코드
// 이후에 다시 설명
OwnerCharacter->StopAnimMontage();
Index++;
const FDoActionData& data = Datas[Index];
OwnerCharacter->PlayAnimMontage(data.AnimMontage, data.PlayRatio, data.StartSection);
data.bCanMove ? Status->SetMove() : Status->SetStop();
}
void ACDoAction_Melee::End_DoAction()
{
Super::End_DoAction();
const FDoActionData& data = Datas[Index];
// 현재 몽타주 중단 시킴
OwnerCharacter->StopAnimMontage(data.AnimMontage);
State->SetIdleMode();
Status->SetMove();
// 다시 처음부터 공격할 수 있게 처리
Index = 0;
}
* BeginAction Notify 만듬(AnimNotify)
다음 동작에 대한 구간을 설정할 AnimNotifyState를 만듬
-> CAnimNotifyState_EnableCombo(시작에는 EnableCombo(), 끝에는 DisableCombo())
EnableCombo -> 콤보 가능
BeginAction -> 다음동작으로 넘김
* Montage FullBody 세팅
이동금지면 FullBody가 정확히 맞다.
* 3번 동작은 다음 넘어가는 동작이 없어서 EndAction만 주면 된다.
CDoAction_Melee.h 추가된 내용
더보기
#pragma once
#include "CoreMinimal.h"
#include "Actions/CDoAction.h"
#include "CDoAction_Melee.generated.h"
UCLASS()
class UONLINE_04_ACTION_API ACDoAction_Melee : public ACDoAction
{
GENERATED_BODY()
...
public:
FORCEINLINE void EnableCombo() { bEnable = true; }
FORCEINLINE void DisableCombo() { bEnable = false; }
private:
bool bExist; // 다음 콤보가 존재하는지
bool bEnable; // 다음 콤보가 허용되었는지
bool bLast; // 콤보의 마지막인지
int32 Index; // 현재 몇번째 콤보중인지
};
CDoAction_Melee.cpp 수정된 내용
더보기
...
void ACDoAction_Melee::DoAction()
{
Super::DoAction();
// 데이터 개수가 0보다 커야함
CheckFalse(Datas.Num() > 0);
// 다음콤보가 허용되었다면
if (bEnable == true)
{
// 다음콤보가 있다고 알려줌
bExist = true;
// 콤보 입력 더이상 하지 말라(이미 들어왔으니까)
bEnable = false;
return;
}
// IdleMode여야 함
CheckFalse(State->IsIdleMode());
State->SetActionMode();
const FDoActionData& data = Datas[0];
OwnerCharacter->PlayAnimMontage(data.AnimMontage, data.PlayRatio, data.StartSection);
data.bCanMove ? Status->SetMove() : Status->SetStop();
}
void ACDoAction_Melee::Begin_DoAction()
{
Super::Begin_DoAction();
CheckFalse(bExist);
bExist = false;
// 현재 플레이 중인 모든 몽타주를 중지시킴
// 이후에 Fist의 마지막 동작을 끊어서 사용하려고 넣은 코드
// 이후에 다시 설명
OwnerCharacter->StopAnimMontage();
Index++;
const FDoActionData& data = Datas[Index];
OwnerCharacter->PlayAnimMontage(data.AnimMontage, data.PlayRatio, data.StartSection);
data.bCanMove ? Status->SetMove() : Status->SetStop();
}
void ACDoAction_Melee::End_DoAction()
{
Super::End_DoAction();
const FDoActionData& data = Datas[Index];
// 현재 몽타주 중단 시킴
OwnerCharacter->StopAnimMontage(data.AnimMontage);
State->SetIdleMode();
Status->SetMove();
// 다시 처음부터 공격할 수 있게 처리
Index = 0;
}
CAnimNotify_BeginAction.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotify.h"
#include "CAnimNotify_BeginAction.generated.h"
UCLASS()
class UONLINE_04_ACTION_API UCAnimNotify_BeginAction : public UAnimNotify
{
GENERATED_BODY()
public:
FString GetNotifyName_Implementation() const override;
virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
CAnimNotify_BeginAction.cpp
더보기
#include "CAnimNotify_BeginAction.h"
#include "Global.h"
#include "Characters/CPlayer.h"
#include "Actions/CActionData.h"
#include "Actions/CDoAction.h"
#include "Components/CActionComponent.h"
FString UCAnimNotify_BeginAction::GetNotifyName_Implementation() const
{
return "BeginAction";
}
void UCAnimNotify_BeginAction::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
Super::Notify(MeshComp, Animation);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCActionComponent* action = CHelpers::GetComponent<UCActionComponent>(MeshComp->GetOwner());
CheckNull(action);
action->GetCurrent()->GetDoAction()->Begin_DoAction();
}
CAnimNotifyState_EnableCombo.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "CAnimNotifyState_EnableCombo.generated.h"
UCLASS()
class UONLINE_04_ACTION_API UCAnimNotifyState_EnableCombo : public UAnimNotifyState
{
GENERATED_BODY()
public:
FString GetNotifyName_Implementation() const override;
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration) override;
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
CAnimNotifyState_EnableCombo.cpp
더보기
#include "CAnimNotifyState_EnableCombo.h"
#include "Global.h"
#include "Actions/CEquipment.h"
#include "Actions/CDoAction_Melee.h"
#include "Components/CActionComponent.h"
FString UCAnimNotifyState_EnableCombo::GetNotifyName_Implementation() const
{
return "EnableCombo";
}
void UCAnimNotifyState_EnableCombo::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration)
{
Super::NotifyBegin(MeshComp, Animation, TotalDuration);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCActionComponent* action = CHelpers::GetComponent<UCActionComponent>(MeshComp->GetOwner());
CheckNull(action);
ACDoAction_Melee* melee = Cast<ACDoAction_Melee>(action->GetCurrent()->GetDoAction());
CheckNull(melee);
melee->EnableCombo();
}
void UCAnimNotifyState_EnableCombo::NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
Super::NotifyEnd(MeshComp, Animation);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCActionComponent* action = CHelpers::GetComponent<UCActionComponent>(MeshComp->GetOwner());
CheckNull(action);
ACDoAction_Melee* melee = Cast<ACDoAction_Melee>(action->GetCurrent()->GetDoAction());
CheckNull(melee);
melee->DisableCombo();
}
결과
'Unreal Engine 4 > C++' 카테고리의 다른 글
<Unreal C++> 48 - Action RPG (Create Enemy & Collision) (0) | 2022.05.16 |
---|---|
<Unreal C++> 47 - Action RPG (Character Interface) (0) | 2022.05.16 |
<Unreal C++> 44 - Action RPG(CAction & Melee Attack) (0) | 2022.05.09 |
<Unreal C++> 43 - Action RPG(Weapon Attachment) (0) | 2022.05.09 |
<Unreal C++> 40 - Action RPG (Action Component & Equip) (0) | 2022.05.09 |