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: 마우스 오른쪽 버튼 처리
}