응애맘마조
231213 강의 본문
캐릭터를 움직이고 검을 들고 공격하고 3타하는 모션을 만들었습니다.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "C_Character.generated.h"
UENUM(BlueprintType)
enum class EEquipState : uint8
{
UNARMED = 0,
SWORD
};
UCLASS()
class SCENEA_API AC_Character : public ACharacter
{
GENERATED_BODY()
private:
bool isRotation;
bool isEquipped;
bool isMove;
int ComboCount;
float ComboDelayTime;
float ComboDelay[2] = { 1.0f,2.0f };
bool isAttacking;
class UMaterialInstanceDynamic* Material;
public:
UPROPERTY(EditDefaultsOnly)
class USpringArmComponent* SpringArm;
UPROPERTY(EditDefaultsOnly)
class UCameraComponent* Camera = nullptr;
UPROPERTY(EditDefaultsOnly)
EEquipState EquipState = EEquipState::UNARMED;
AC_Character();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void OnMoveForward(float Axis);
void OnMoveRight(float Axis);
void OnRotationYaw(float Axis);
void OnRotationPitch(float Axis);
void CamRotationLock();
void CamRotationUnLock();
void OnRunning();
void OnWalking();
void OnJumpping();
UFUNCTION(BlueprintCallable)
void ChangeColor(FLinearColor color);
void OnAttack();
void OnSelectSword();
void EquipSword();
void EquipedSword();
void UnEquipSword();
void UnEquipedSword();
FORCEINLINE bool GetIsEquipped() { return isEquipped; }
FORCEINLINE void SetIsMove(bool ismove) { isMove = ismove; }
FORCEINLINE void SetIsAttacking(bool b) { isAttacking = b; }
void SetDelayTime();
private:
class AC_Swrod* Sword;
class UAnimMontage* _EquipSword;
class UAnimMontage* _UnEquipSword;
class UAnimMontage* _SwordAttack;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "C_Character.h"
#include "Global.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Materials/MaterialInstanceConstant.h"
#include "Animation/AnimMontage.h"
#include "Scene3/C_Swrod.h"
// Sets default values
AC_Character::AC_Character()
{
ComboCount = 1;
ComboDelayTime = 0.0f;
isAttacking = false;
isRotation = false;
isEquipped = false;
isMove = true;
// 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;
//메시 컴포넌트 안에(기존에있던 컴포넌트) 스켈레탈메시 로드해서 붙이기
USkeletalMesh* mesh;
CHelpers::GetAsset< USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
/*SpringArm = CreateDefaultSubobject<USpringArmComponent>("SpringArm");
SpringArm->SetupAttachment(GetCapsuleComponent());*/
CHelpers::CreateComponent< USpringArmComponent>(this, &SpringArm, "SpringArm",
GetCapsuleComponent());
CHelpers::CreateComponent< UCameraComponent>(this, &Camera, "Camera",
SpringArm);
SpringArm->SetRelativeLocation(FVector(-30, 0, 60));
SpringArm->SetRelativeRotation(FRotator(-30, 0, 0));
SpringArm->bUsePawnControlRotation = true;
TSubclassOf<UAnimInstance> animInstance;
CHelpers::GetClass< UAnimInstance>(&animInstance,
"AnimBlueprint'/Game/Scene2/BP/ABP_C_Character.ABP_C_Character_C'");
GetMesh()->SetAnimInstanceClass(animInstance);
GetCharacterMovement()->MaxWalkSpeed = 300.0f;
GetCharacterMovement()->JumpZVelocity = 1000.0f;
CHelpers::GetAsset<UAnimMontage>(&_EquipSword, "AnimMontage'/Game/Character/Animations/OneHand/Draw_Sword_Montage.Draw_Sword_Montage'");
CHelpers::GetAsset<UAnimMontage>(&_UnEquipSword, "AnimMontage'/Game/Character/Animations/OneHand/Sheath_Sword_Montage.Sheath_Sword_Montage'");
CHelpers::GetAsset<UAnimMontage>(&_SwordAttack, "AnimMontage'/Game/Character/Animations/OneHand/Sword_Attack_Montage.Sword_Attack_Montage'");
}
// Called when the game starts or when spawned
void AC_Character::BeginPlay()
{
Super::BeginPlay();
UMaterialInstanceConstant* material;
CHelpers::GetAssetDynamic<UMaterialInstanceConstant>(&material,
L"MaterialInstanceConstant'/Game/Character/Materials/M_UE4Man_Body_Inst.M_UE4Man_Body_Inst'");
Material = UMaterialInstanceDynamic::Create(material, this);
GetMesh()->SetMaterial(0, Material);
Sword = AC_Swrod::Spawn(GetWorld(), this);
Sword->UnEquip();
}
// Called every frame
void AC_Character::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (ComboDelayTime > 0.0f)
{
ComboDelayTime -= DeltaTime;
if (ComboDelayTime <= 0.0f) ComboCount = 1;
}
}
// Called to bind functionality to input
void AC_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &AC_Character::OnMoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AC_Character::OnMoveRight);
PlayerInputComponent->BindAction("CamRotationLock", EInputEvent::IE_Pressed, this,
&AC_Character::CamRotationUnLock);
PlayerInputComponent->BindAction("CamRotationLock", EInputEvent::IE_Released, this,
&AC_Character::CamRotationLock);
PlayerInputComponent->BindAxis("RotationYaw", this, &AC_Character::OnRotationYaw);
PlayerInputComponent->BindAxis("RotationPitch", this, &AC_Character::OnRotationPitch);
PlayerInputComponent->BindAction("PressRun", EInputEvent::IE_Pressed, this,
&AC_Character::OnRunning);
PlayerInputComponent->BindAction("PressRun", EInputEvent::IE_Released, this,
&AC_Character::OnWalking);
PlayerInputComponent->BindAction("Jumping", EInputEvent::IE_Pressed, this,
&AC_Character::OnJumpping);
PlayerInputComponent->BindAction("SelectSword", EInputEvent::IE_Pressed, this,
&AC_Character::OnSelectSword);
PlayerInputComponent->BindAction("Attack", EInputEvent::IE_Pressed, this,
&AC_Character::OnAttack);
}
void AC_Character::OnMoveForward(float Axis)
{
if (!isMove) return;
FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
FVector dir = FQuat(rotator).GetForwardVector().GetSafeNormal2D();
AddMovementInput(dir, Axis);
}
void AC_Character::OnMoveRight(float Axis)
{
if (!isMove) return;
FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
FVector dir = FQuat(rotator).GetRightVector().GetSafeNormal2D();
AddMovementInput(dir, Axis);
}
void AC_Character::OnRotationYaw(float Axis)
{
if(isRotation)
AddControllerYawInput(Axis);
}
void AC_Character::OnRotationPitch(float Axis)
{
if (isRotation)
AddControllerPitchInput(Axis);
}
void AC_Character::CamRotationLock()
{
isRotation = false;
}
void AC_Character::CamRotationUnLock()
{
isRotation = true;
}
void AC_Character::OnRunning()
{
GetCharacterMovement()->MaxWalkSpeed = 1000.0f;
}
void AC_Character::OnWalking()
{
GetCharacterMovement()->MaxWalkSpeed = 300.0f;
}
void AC_Character::OnJumpping()
{
Jump();
}
void AC_Character::ChangeColor(FLinearColor color)
{
Material->SetVectorParameterValue("BodyColor", color);
}
void AC_Character::SetDelayTime()
{
if (ComboCount == 3)
{
ComboDelayTime = 0.0f;
ComboCount = 1;
}
ComboDelayTime = ComboDelay[ComboCount -1];
}
void AC_Character::OnAttack()
{
if (EquipState == EEquipState::SWORD && !isAttacking)
{
if (ComboDelayTime > 0.0f)
{
ComboCount++;
if (ComboCount > 3)
{
ComboCount = 1;
ComboDelayTime = 0.0f;
}
}
FString str = "Attack";
str.Append(FString::FromInt(ComboCount));
PlayAnimMontage(_SwordAttack, 1.0f, FName(str));
}
}
void AC_Character::OnSelectSword()
{
isEquipped = !isEquipped;
if (isEquipped)
{
EquipState = EEquipState::SWORD;
PlayAnimMontage(_EquipSword);
}
else
{
EquipState = EEquipState::UNARMED;
PlayAnimMontage(_UnEquipSword);
}
}
void AC_Character::EquipSword()
{
isMove = false;
bUseControllerRotationYaw = true;
GetCharacterMovement()->bOrientRotationToMovement = false;
GetCharacterMovement()->RotationRate.Yaw = 0.0f;
}
void AC_Character::EquipedSword()
{
isMove = true;
Sword->Equip();
}
void AC_Character::UnEquipSword()
{
isMove = false;
GetCharacterMovement()->RotationRate.Yaw = 360.0f;
}
void AC_Character::UnEquipedSword()
{
isMove = true;
Sword->UnEquip();
bUseControllerRotationYaw = false;
GetCharacterMovement()->bOrientRotationToMovement = true;
}
캐릭터의 움직임 모션을 C++로 언리얼 엔진에서 실행할 수 있게 클래스로 정리했습니다.
읽어주셔서 감사합니다.
Comments