Unreal5 무기 생성 및 장착 C++

250x250

Unreal5 무기 생성 및 장착 C++.

*이 글은 공부하면서 작성하는 글이며, 이전글과 이어지는 글이므로 이해하기 위해서는 이전글 확인이 필요할 수 있습니다.

[프로그래밍/언리얼] - Unreal5 Overlap C++

 

Unreal5 Overlap C++

Unreal5 Overlap C++ *그냥 공부하면서 작성하는 글입니다. 이 글은 이전글과 이어지는 글이므로 이해하기 위해서는 이전글이 필요할 수 있습니다. [프로그래밍/언리얼] - Unreal5 Foot IK Unreal5 Foot IK Unreal

intunknown.tistory.com

  • RightHandSocket 생성 및 위치 조절.
  • Weapon Class 생성 및 코드 작성.
  • 실행.

RightHandSocket 생성.

Skeleton으로 가서 오른손에 Socket을 생성해 줍니다.

저는 RightHandSocket을 생성했습니다.

Socket을 생성하고, Add Preview Asset으로 손에 무기가 잡히면 어떻게 생겼을지 확인하고, 추가할 무기가 자연스럽게 손에 잡히도록 배치합니다.

소켓 생성하면서 보니까 파라곤 에셋에 무기가 뼈로 돼있어서 좀 지저분해 보이길래 Blueprint에서 대충 본을 숨겨줍니다.

Weapon Class 생성 및 코드 작성.

Weapon 클래스는 이전에 만들었던 Item class를 상속받아 만들었습니다.

Overlap이벤트 발생 && EKey를 눌렀을 때 Weapon의 Equip() 함수를 실행합니다.

대충 이런 내용이 아래 코드들입니다.

Item.cpp 코드는 이렇습니다.

(저번글에서 만들었던 SIn함수는 잠시 주석처리 했습니다.)

저번 글에서 구현했던 Overlap함수를 이용해 사용자가 무기에 접근하면 AItem class를 SlayerCharacter에 넘겨줍니다.

//#include "Character/SlayerCharacter.h"
void AItem::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{ 
	if (ASlayerCharacter* SlayerCharacter = Cast<ASlayerCharacter>(OtherActor)) {
		SlayerCharacter->SetOverlappingItem(this);
	}
}
void AItem::OnSphereOverlapOut(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	if (ASlayerCharacter* SlayerCharacter = Cast<ASlayerCharacter>(OtherActor)) {
		SlayerCharacter->SetOverlappingItem(nullptr);
	}
}

캐릭터(SlayerCharacter class)에서 장비를 장착할 수 있도록 InputAction을 추가하고, 해당 키를 눌렀을 때 실행할 함수도 설정합니다.

그리고 Item클래스에서 넘겨준 AItem을 저장합니다.

추가한 코드는 다음과 같습니다.

//SlayerCharacter.h
/*Equip*/
class AItem;
protected:
	//Equip
	UPROPERTY(EditAnywhere, Category = Input)
	UInputAction* EkeyAction;
	void EkeyPress();
private:
	//Equip
	UPROPERTY(VisibleInstanceOnly)
	AItem* OverlappingItem;
public:
	FORCEINLINE void SetOverlappingItem(AItem* Item) { OverlappingItem = Item; }

SlayerCharacter.cpp는 이렇게 추가해줬습니다.

Item Class의 Sphere component안에 Player가 들어오면 Overlapping을 SlayerCharacter에 넘기게 되고, EKey를 눌렀을 때 그 데이터가 있다면 Weapon의 Equip함수를 실행합니다.

void ASlayerCharacter::EkeyPress()
{
	/*Equip*/
	//#include "Item/Weapons/Weapon.h"
	if (AWeapon* Weapon = Cast<AWeapon>(OverlappingItem)) {
		Weapon->Equip(GetMesh(),FName("RightHandSocket"));
		OverlappingItem = nullptr;
	}
}
void ASlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	//#include "EnhancedInputComponent.h"추가.
	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
		EnhancedInputComponent->BindAction(MovementAction, ETriggerEvent::Triggered, this, &ASlayerCharacter::Move);
		EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ASlayerCharacter::Jump);
		EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ASlayerCharacter::Look);
		EnhancedInputComponent->BindAction(EkeyAction, ETriggerEvent::Triggered, this, &ASlayerCharacter::EkeyPress);
	}
}

Weapon.h에 함수 두 개가 있는데 그냥 하나를 둘로 나눠놓은 것입니다.

#pragma once

#include "CoreMinimal.h"
#include "Item/Item.h"
#include "Weapon.generated.h"

UCLASS()
class SLAYER_API AWeapon : public AItem
{
	GENERATED_BODY()
public:
	void Equip(USceneComponent* InParent,const FName& InSocketName);
	void AttachMeshToSocket(USceneComponent* InParent, const FName& InSocketName);
};

Weapon.cpp 장착하는 함수입니다.

#include "Item/Weapons/Weapon.h"
/*Equip*/
#include "Engine/EngineTypes.h"
#include "Components/SphereComponent.h"
void AWeapon::Equip(USceneComponent* InParent, const FName& InSocketName)
{
	AttachMeshToSocket(InParent, InSocketName);
	//#include "Components/SphereComponent.h"
	if (Sphere) {
		Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}
}
void AWeapon::AttachMeshToSocket(USceneComponent* InParent, const FName& InSocketName)
{
	//#include "Engine/EngineTypes.h"
	FAttachmentTransformRules TransformRules(EAttachmentRule::SnapToTarget, true);
	ItemMesh->AttachToComponent(InParent, TransformRules, InSocketName);
}

실행

Weapon 클래스를 블루프린트로 상속해서 카타나를 하나 만들었습니다.

무기에 가서 EKey를 눌러보면 이런 식으로 장착이 됩니다.

일단은 무기를 손에 잡는 것만 생각하고 만들었더니 장착해제도 못하고, 문제점이 좀 있네요.

 

 

Designed by JB FACTORY