Test 때문에 빠진게 많음-

Aim 문제로 인해서. 캐릭터 Aim을 1인칭으로 줄 것

1st 애니메이션 및 스켈레톤 가져왔음.

Untitled

Untitled

[C로 불러오고 적용이 안될 때 불러 들인 것에 대한 것을 리로드 해줘서 재 배치 가 가능하다]

Untitled

CRifle_Aim.h = 기존 CRifle.h 를 파일명만 바꿔 주었다.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CRifle_Aim.generated.h"

UCLASS()
class U2110_03_API ACRifle_Aim : public AActor
{
	GENERATED_BODY()
	
private:

private:
	UPROPERTY(VisibleDefaultsOnly)
		class UCameraComponent* Camera;

	UPROPERTY(VisibleDefaultsOnly)
		class USkeletalMeshComponent* CharacterMesh;

	UPROPERTY(VisibleDefaultsOnly)
		class USkeletalMeshComponent* Mesh;

public:
	static ACRifle_Aim* Spawn(TSubclassOf<ACRifle_Aim> RifleClass, class ACharacter* InOwner);

public:	
	ACRifle_Aim();

public:
	void Equip();
	void Begin_Equip();
	void End_Equip();

private:
	void Unequip();
public:
	void Begin_Unequip();
	void End_Unequip();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

private:
	class ACharacter* OwnerCharacter;
};

CRifle_Aim.cpp

#include "CRifle_Aim.h"
#include "Global.h"
#include "Animation/AnimMontage.h"
#include "Components/SkeletalMeshComponent.h"
#include "GameFramework/Character.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Camera/CameraComponent.h"

ACRifle_Aim::ACRifle_Aim()
{
	PrimaryActorTick.bCanEverTick = true;

	CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera");
	CHelpers::CreateComponent<USkeletalMeshComponent>(this, &CharacterMesh, "CharacterMesh", Camera);
	CHelpers::CreateComponent<USkeletalMeshComponent>(this, &Mesh, "Mesh", CharacterMesh, "GripPoint");

	USkeletalMesh* mesh;
	
	CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh_1st/Mesh/SK_Mannequin_Arms.SK_Mannequin_Arms'");
	CharacterMesh->SetSkeletalMesh(mesh);
	CharacterMesh->SetRelativeLocation(FVector(3.3f, -4.5f, -161.3f));
	CharacterMesh->SetRelativeRotation(FRotator(1.92f, -20.0f, 5.3f));

//클래스 타입으로
	TSubclassOf<UAnimInstance> animInstance;
	CHelpers::GetClass<UAnimInstance>(&animInstance, "AnimBlueprint'/Game/05_TPS/ABP_Rifle_1st.ABP_Rifle_1st_C'");
	CharacterMesh->SetAnimClass(animInstance);
//애님클래스 들어가지 않아서. 블프에서 수동으로 설정 ABP설정 
	
	CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Weapons/Meshes/SK_AR4.SK_AR4'");
	Mesh->SetSkeletalMesh(mesh);
}

ACRifle_Aim* ACRifle_Aim::Spawn(TSubclassOf<ACRifle_Aim> RifleClass, class ACharacter* InOwner)
{
	FActorSpawnParameters params;
	params.Owner = InOwner;

	return InOwner->GetWorld()->SpawnActor<ACRifle_Aim>(RifleClass, params);
}

void ACRifle_Aim::BeginPlay()
{
	Super::BeginPlay();

	OwnerCharacter = Cast<ACharacter>(GetOwner());
//socket에 Aim 
	AttachToComponent(OwnerCharacter->GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), "Rifle_Aim");

	OwnerCharacter->GetMesh()->SetVisibility(false, true);
	OwnerCharacter->GetController<APlayerController>()->SetViewTargetWithBlend(this);
}

void ACRifle_Aim::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	
}

void ACRifle_Aim::Equip()
{
	
}

void ACRifle_Aim::Begin_Equip()
{
	
}

void ACRifle_Aim::End_Equip()
{
	
}

void ACRifle_Aim::Unequip()
{
	
}

void ACRifle_Aim::Begin_Unequip()
{
	
}

void ACRifle_Aim::End_Unequip()
{
	
}

CRifle_Aim.cpp

void ACRifle_Aim::BeginPlay()
{
	Super::BeginPlay();

	OwnerCharacter = Cast<ACharacter>(GetOwner());
	AttachToComponent(OwnerCharacter->GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), "Rifle_Aim");

	OwnerCharacter->GetMesh()->SetVisibility(false, true);
	OwnerCharacter->GetController<APlayerController>()->SetViewTargetWithBlend(this);
}

GetController 에서 SetViewTargetWithBlend 가져 올 수 있다.

플레이어 메쉬 꺼지고. 카메라가 이쪽으로 전환되는

CHelpers.h

//Mesh를 어딘가에 붙일 때 SetupAttachment를 사용한다.(BeginPlay에서는 사용할 수 없다) 최초에 붙는 만들면서 생성 되었을 때 붙여주는  

template<typename T>
	static void CreateComponent(AActor* InActor, T** OutComponent, FName InName, USceneComponent* InParent = nullptr, FName InSocketName = NAME_None)
	{
		*OutComponent = InActor->CreateDefaultSubobject<T>(InName);

		if (!!InParent)
		{
//아무것도 안 썼을 때는 SetupAttachment에 Root로 들어가고, 소켓이름을 사용하면 소켓에 붙일 수 있을 것이다. 
			(*OutComponent)->SetupAttachment(InParent, InSocketName);

			return;
		}

		InActor->SetRootComponent(*OutComponent);
	}

Untitled

FName InSocketName = NAME_None : name_none이 기본값 부모가 있어야 사용가능

SetupAttachment : 처음에 SceneComponent가 들어가고, 그다음에 소켓이름이 Name_None으로 Default 값이 들어간다. (소켓을 어디에 붙일 것인가?)

Untitled

그래서 입력 하였다면 이런식으로 붙인다.

CHelpers::CreateComponent<USkeletalMeshComponent>(this, &Mesh, "Mesh", CharacterMesh, "GripPoint");

CPlayer.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "05_TPS/IRifle.h"
#include "CPlayer.generated.h"

UCLASS()
class U2110_03_API ACPlayer 
	: public ACharacter
	, public IIRifle
{
	GENERATED_BODY()

private:
	UPROPERTY(EditDefaultsOnly, Category = "Rifle")
		TSubclassOf<class ACRifle_Aim> Rifle_AimClass;

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USpringArmComponent* SpringArm;

	UPROPERTY(VisibleDefaultsOnly)
		class UCameraComponent* Camera;

public:
	ACPlayer();

	bool GetEquipped() override;
	bool GetAiming_Rifle() override;
	
	void Begin_Equip_Rifle() override;
	void End_Equip_Rifle() override;

	void Begin_Unequip_Rifle() override;
	void End_Unequip_Rifle() override;

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

private:
	void OnMoveForward(float InAxisValue);
	void OnMoveRight(float InAxisValue);
	void OnVerticalLook(float InAxisValue);
	void OnHorizontalLook(float InAxisValue);

public:
	void OnRun();
	void OffRun();

	void OnRifle();

	void OnSubAction();
	void OffSubAction();

public:
	UFUNCTION(BlueprintCallable, Category = "Color")
		void ChangeColor(FLinearColor InColor);

private:
	class UMaterialInstanceDynamic* Materials[2];

private:
	class ACRifle_Aim* Rifle_Aim;
};

CPlayer.cpp

#include "CPlayer.h"
#include "Global.h"
#include "05_TPS/CRifle_Aim.h"
#include "CAnimInstance.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/InputComponent.h"
#include "Materials/MaterialInstanceDynamic.h"

ACPlayer::ACPlayer()
{
	PrimaryActorTick.bCanEverTick = true;

	CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetCapsuleComponent());
	CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);

	bUseControllerRotationYaw = false;
	GetCharacterMovement()->bOrientRotationToMovement = true;
	GetCharacterMovement()->MaxWalkSpeed = 400;
	

	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));

	TSubclassOf<UCAnimInstance> animInstance;
	CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
	GetMesh()->SetAnimClass(animInstance);

	SpringArm->SetRelativeLocation(FVector(0, 0, 60));
	SpringArm->TargetArmLength = 200;
	SpringArm->bDoCollisionTest = false;
	SpringArm->bUsePawnControlRotation = true;
	SpringArm->SocketOffset = FVector(0, 60, 0);
	SpringArm->bEnableCameraLag = true;

	
	CHelpers::GetClass<ACRifle_Aim>(&Rifle_AimClass, "Blueprint'/Game/05_TPS/BP_CRifle_Aim.BP_CRifle_Aim_C'");
}

void ACPlayer::BeginPlay()
{
	Super::BeginPlay();

	TArray<UMaterialInterface*> materials = GetMesh()->GetMaterials();
	for (int32 i = 0; i < materials.Num(); i++)
	{
		Materials[i] = UMaterialInstanceDynamic::Create(materials[i], this);
		GetMesh()->SetMaterial(i, Materials[i]);
	}

	Rifle_Aim = ACRifle_Aim::Spawn(Rifle_AimClass, this);
}

void ACPlayer::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	PlayerInputComponent->BindAxis("MoveForward", this, &ACPlayer::OnMoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &ACPlayer::OnMoveRight);
	PlayerInputComponent->BindAxis("VerticalLook", this, &ACPlayer::OnVerticalLook);
	PlayerInputComponent->BindAxis("HorizontalLook", this, &ACPlayer::OnHorizontalLook);

	PlayerInputComponent->BindAction("Run", EInputEvent::IE_Pressed, this, &ACPlayer::OnRun);
	PlayerInputComponent->BindAction("Run", EInputEvent::IE_Released, this, &ACPlayer::OffRun);

	PlayerInputComponent->BindAction("Rifle", EInputEvent::IE_Pressed, this, &ACPlayer::OnRifle);

	PlayerInputComponent->BindAction("SubAction", EInputEvent::IE_Pressed, this, &ACPlayer::OnSubAction);
	PlayerInputComponent->BindAction("SubAction", EInputEvent::IE_Released, this, &ACPlayer::OffSubAction);
}

void ACPlayer::OnMoveForward(float InAxisValue)
{
	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
	FVector direction = FQuat(rotator).GetForwardVector().GetSafeNormal2D();

	AddMovementInput(direction, InAxisValue);
}

void ACPlayer::OnMoveRight(float InAxisValue)
{
	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
	FVector direction = FQuat(rotator).GetRightVector().GetSafeNormal2D();

	AddMovementInput(direction, InAxisValue);
}

void ACPlayer::OnVerticalLook(float InAxisValue)
{
	AddControllerPitchInput(InAxisValue);
}

void ACPlayer::OnHorizontalLook(float InAxisValue)
{
	AddControllerYawInput(InAxisValue);
}

void ACPlayer::OnRun()
{
	GetCharacterMovement()->MaxWalkSpeed = 600;
}

void ACPlayer::OffRun()
{
	GetCharacterMovement()->MaxWalkSpeed = 400;
}

void ACPlayer::OnRifle()
{
	//Rifle->Equip();
}

void ACPlayer::ChangeColor(FLinearColor InColor)
{
	for (UMaterialInstanceDynamic* material : Materials)
		material->SetVectorParameterValue("BodyColor", InColor);
}

bool ACPlayer::GetEquipped()
{
	//if (!!Rifle)
	//	return Rifle->GetEquipped();

	return false;
}

bool ACPlayer::GetAiming_Rifle()
{
	//if (!!Rifle)
	//	return Rifle->GetAiming();

	return false;
}

void ACPlayer::Begin_Equip_Rifle()
{
	//Rifle->Begin_Equip();
}

void ACPlayer::End_Equip_Rifle()
{
	//Rifle->End_Equip();
}

void ACPlayer::Begin_Unequip_Rifle()
{
	//Rifle->Begin_Unequip();
}

void ACPlayer::End_Unequip_Rifle()
{
	//Rifle->End_Unequip();
}

void ACPlayer::OnSubAction()
{
	//if(!!Rifle)
	//{ 
	//	Rifle->Begin_Aim();

	//	return;
	//}
		
	//TODO: 마우스 오른쪽 버튼 처리
}

void ACPlayer::OffSubAction()
{
	//if (!!Rifle)
	//{
	//	Rifle->End_Aim();

	//	return;
	//}

	//TODO: 마우스 오른쪽 버튼 처리
}