응애맘마조

231215 강의 본문

공부/UE강의

231215 강의

TH.Wert 2023. 12. 15. 20:39

어제 말했던 대로 총을 드는 모션의 애니메이션을 추가하고 프레임 단위로 편집하여 넣는 효과를 냈습니다.

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입니다.

실행 영상

아직 완전히 다 구현되지는 않았습니다. 총을 들었을 때 좌우로는 움직이지만 상하로는 움직이게 했는데 아직 문제점을 찾지 못하고 다음 주 월요일은 셋째 주라서 쉬고 그 다음날 화요일에 해결한다고 했습니다.

 

읽어주셔서 감사합니다.

'공부 > UE강의' 카테고리의 다른 글

231220 강의  (0) 2023.12.20
231219 강의  (0) 2023.12.19
231214 강의  (0) 2023.12.14
231213 강의  (0) 2023.12.13
231212 강의  (0) 2023.12.12
Comments