응애맘마조
231215 강의 본문
어제 말했던 대로 총을 드는 모션의 애니메이션을 추가하고 프레임 단위로 편집하여 넣는 효과를 냈습니다.
Mixamo 사이트에서 쉽게 찾을 수 있었습니다.
총을 들고 좌우 회전과 상하 회전을 넣는데 모여있는 효과에서 프레임 단위로 잘라서 사용할 수 있습니다.
약간 FSM 같은 느낌으로 1번을 눌렀을 때 검, 2번을 눌렀을 때 총, 같은 키를 눌렀을 때 디폴트로 돌아오는 형식으로 했습니다.
// 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));
// p,y,r
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
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("SelectRifle", EInputEvent::IE_Pressed, this,
&AC_Character::OnSelectRifle);
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 || EquipState == EEquipState::RIFLE)
{
AddControllerYawInput(Axis);
}
}
void AC_Character::OnRotationPitch(float Axis)
{
if (isRotation || EquipState == EEquipState::RIFLE)
{
AddControllerPitchInput(Axis);
}
}
void AC_Character::CamRotationLock()
{
isRotation = false;
}
void AC_Character::CamRotationUnLock()
{
isRotation = true;
}
void AC_Character::OnRunning()
{
if(EquipState <= EEquipState::SWORD)
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)
{
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::OnSelectRifle()
{
if (EquipState != EEquipState::RIFLE)
{
EquipState = EEquipState::RIFLE;
bUseControllerRotationYaw = true;
GetCharacterMovement()->bOrientRotationToMovement = false;
GetCharacterMovement()->RotationRate.Yaw = 0.0f;
}
else
{
EquipState = EEquipState::UNARMED
}
}
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;
}
Character.cpp입니다.
아직 완전히 다 구현되지는 않았습니다. 총을 들었을 때 좌우로는 움직이지만 상하로는 움직이게 했는데 아직 문제점을 찾지 못하고 다음 주 월요일은 셋째 주라서 쉬고 그 다음날 화요일에 해결한다고 했습니다.
읽어주셔서 감사합니다.
Comments