Test 때문에 빠진게 많음-
Aim 문제로 인해서. 캐릭터 Aim을 1인칭으로 줄 것
1st 애니메이션 및 스켈레톤 가져왔음.


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

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

FName InSocketName = NAME_None : name_none이 기본값 부모가 있어야 사용가능
SetupAttachment : 처음에 SceneComponent가 들어가고, 그다음에 소켓이름이 Name_None으로 Default 값이 들어간다. (소켓을 어디에 붙일 것인가?)

그래서 입력 하였다면 이런식으로 붙인다.
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: 마우스 오른쪽 버튼 처리
}