기존 에셋 제외하고(백업)
에셋 탐색 할 때 부모 부터 보면서 점진적으로 확인하고, 필요없는 것을 끊어보고 확인하면서. 해당 만약 찾고자 하는 것이 Aim 이라면, Aim부근이 끊기는지 확인을 해본다.
해당 FPS_TPS에셋을 사용하였다.
CPlayer.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CPlayer.generated.h"
UCLASS()
class U2110_03_API ACPlayer
: public ACharacter
{
GENERATED_BODY()
private:
UPROPERTY(VisibleDefaultsOnly)
class USpringArmComponent* SpringArm;
UPROPERTY(VisibleDefaultsOnly)
class UCameraComponent* FpsCamera;
UPROPERTY(VisibleDefaultsOnly)
class UArrowComponent* ArmsPosition;
UPROPERTY(VisibleDefaultsOnly)
class UArrowComponent* WeaponFeelArrowMain;
UPROPERTY(VisibleDefaultsOnly)
class UArrowComponent* WeaponFeelArrowAim;
UPROPERTY(VisibleDefaultsOnly)
class USkeletalMeshComponent* FirstArms;
UPROPERTY(VisibleDefaultsOnly)
class UArrowComponent* DirectionArrow;
public:
ACPlayer();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//virtual void Fire_Rifle() override;
private:
void OnMoveForward(float InAxisValue);
void OnMoveRight(float InAxisValue);
void OnVerticalLook(float InAxisValue);
void OnHorizontalLook(float InAxisValue);
public:
void OnRun();
void OffRun();
void OnSubAction();
void OffSubAction();
void OnFire();
void OffFire();
void OnAutoFire();
public:
UFUNCTION(BlueprintCallable, Category = "Color")
void ChangeColor(FLinearColor InColor);
private:
class UMaterialInstanceDynamic* Materials[2];
};
CPlayer.cpp
#include "CPlayer.h"
#include "Global.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 "Components/ArrowComponent.h"
#include "Materials/MaterialInstanceDynamic.h"
ACPlayer::ACPlayer()
{
PrimaryActorTick.bCanEverTick = true;
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetMesh(), **"VB Camera"**);
CHelpers::CreateComponent<UCameraComponent>(this, &FpsCamera, "Fps", SpringArm);
CHelpers::CreateComponent<UArrowComponent>(this, &ArmsPosition, "ArmsPosition", FpsCamera);
CHelpers::CreateComponent<UArrowComponent>(this, &WeaponFeelArrowMain, "WeaponFeelArrowMain", ArmsPosition);
CHelpers::CreateComponent<UArrowComponent>(this, &WeaponFeelArrowAim, "WeaponFeelArrowAim", WeaponFeelArrowMain);
CHelpers::CreateComponent<USkeletalMeshComponent>(this, &FirstArms, "FirstArms", WeaponFeelArrowAim);
CHelpers::CreateComponent<UArrowComponent>(this, &DirectionArrow, "DirectionArrow", FirstArms);
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->SetRelativeRotation(FRotator(0, 90, 0));
SpringArm->SocketOffset = FVector(0, 0, 10);
SpringArm->TargetArmLength = 0;
FpsCamera->SetRelativeLocation(FVector(-30, 0, 0));
FpsCamera->FieldOfView = 72;
FpsCamera->bUsePawnControlRotation = true;
ArmsPosition->SetRelativeLocation(FVector(-1.93f, 0, -14.3f));
WeaponFeelArrowAim->SetRelativeLocation(FVector(37.44f, 0, 0));
FirstArms->SetRelativeLocation(FVector(-31.75f, 0, -151.11f));
FirstArms->SetRelativeRotation(FRotator(0, -90, 0));
}
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]);
}
}
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("SubAction", EInputEvent::IE_Pressed, this, &ACPlayer::OnSubAction);
PlayerInputComponent->BindAction("SubAction", EInputEvent::IE_Released, this, &ACPlayer::OffSubAction);
PlayerInputComponent->BindAction("Fire", EInputEvent::IE_Pressed, this, &ACPlayer::OnFire);
PlayerInputComponent->BindAction("Fire", EInputEvent::IE_Released, this, &ACPlayer::OffFire);
PlayerInputComponent->BindAction("AutoFire", EInputEvent::IE_Pressed, this, &ACPlayer::OnAutoFire);
}
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::ChangeColor(FLinearColor InColor)
{
for (UMaterialInstanceDynamic* material : Materials)
material->SetVectorParameterValue("BodyColor", InColor);
}
void ACPlayer::OnSubAction()
{
}
void ACPlayer::OffSubAction()
{
}
void ACPlayer::OnFire()
{
}
void ACPlayer::OffFire()
{
}
void ACPlayer::OnAutoFire()
{
}
CRifle.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CRifle.generated.h"
UCLASS()
class U2110_03_API ACRifle : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleDefaultsOnly)
class UArrowComponent* Arrow; //Arrow 선 추가
UPROPERTY(VisibleDefaultsOnly)
class USkeletalMeshComponent* Mesh;
public:
ACRifle();
protected:
virtual void BeginPlay() override;
};
// 새로운 총기 모형 사용
CRifle.cpp
#include "CRifle.h"
#include "Global.h"
#include "Components/ArrowComponent.h"
#include "Components/SkeletalMeshComponent.h"
ACRifle::ACRifle()
{
CHelpers::CreateComponent<UArrowComponent>(this, &Arrow, "Arrow"); // Arrow생성
CHelpers::CreateComponent<USkeletalMeshComponent>(this, &Mesh, "Mesh", Arrow); // Mesh에 Arrow 부착
Arrow->SetRelativeRotation(FRotator(0, 180, 0));
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Weapons/Meshes/SK_wpn_cs_assaultrifle_Mesh.SK_wpn_cs_assaultrifle_Mesh'");
Mesh->SetRelativeRotation(FRotator(0, -90, 0));
Mesh->SetSkeletalMesh(mesh);
}
void ACRifle::BeginPlay()
{
Super::BeginPlay();
}
가상본 을 추가 하게 되면, 만약 Root로 기준을 잡고 다른 곳에 위치 시킬 수도 있다.
그런데. 만약 에셋을 열다보면 Root로 기준 잡혀 있는데. 카메라는 다른곳에 있는 경우가 있다.
이경우는 . 애니메이션 블루프린트 자체에서 처리하는 경우가 대부분 이기 때문에. 잘 확인해서 처리하면 된다.
가상본을 할당해주고 전에도 다룬 적은 있지만. 다시 한번더 확인해 보자
본 트랜스폼 (변경)
Replace Existing : 값이 한번에 바껴야 할 때
Component Space :
실제 Root (Pelvis (Root)) → World
로컬 : 본 수정 불가(만약 한다면. 다 틀어져 버린다. _ 심지어 애니메이션도 틀어져 버린다. ) - 기존 애니메이션 값에 로컬공간이 잘못 틀어져 있다면. 캐릭터에도 영향이 간다.
메시 : 언리얼 설정에 의한 것 본마다 레이어 블렌딩 에 으로 적용되는 것 Mesh Rotation 체크 등을 하여서 생기는 것 메시공간에서 회전이 일어난다.
컴포넌트 : 사용자가 직접 임의로 변경하기 위한 공간
ex)
어떤 애니메이션 노드 → 로컬을 컴포넌트로 → ___________ → 컴포넌트를 로컬로 →
그래서 바로 연결하여서 사용하면 문제가 생길 수 있다.