언리얼 C++ 게임 개발의 정석/9.아이템 상자와 무기 제작

9.1 캐릭터 소켓 설정 및 무기 액터 제작

ftftgop3 2024. 4. 11. 21:06

소켓 

언리얼 엔진에서 캐릭터에 무기나 액세서리를 부착 하기 위한 도구

캐릭터의 스켈레탈 메시의 오른쪽 손에 hand_rsocket 사용

1. 소켓에 프리뷰 애셋 으로 무기 추가

2. 프리뷰 애니메이션으로 애니메이션 상태에서 소켓의 위치 조정

 

ABCharacter.h

무기 애셋을 스켈레탈 메시 컴포넌트로 로딩

SetupAttachment 함수로 무기를 캐릭터에 부착

UPROPERTY(VisibleAnywhere, Category = Weapon)
	USkeletalMeshComponent* Weapon;
        
        
        
 AABCharacter::AABCharacter()
{
	FName WeaponSocket(TEXT("hand_rSocket"));
    //소캣 확인
	if (GetMesh()->DoesSocketExist(WeaponSocket))
	{
		Weapon = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WEAPON"));
		static ConstructorHelpers::FObjectFinder<USkeletalMesh> SK_WEAPON(TEXT("/Game/InfinityBladeWeapons
        /Weapons/Blade/Swords/Blade_BlackKnight/SK_Blade_BlackKnight.SK_Blade_BlackKnight"));
		if (SK_WEAPON.Succeeded())
		{
			Weapon->SetSkeletalMesh(SK_WEAPON.Object);
		}
        //해당 소캣에 무기 부착
		Weapon->SetupAttachment(GetMesh(), WeaponSocket);
	}
}

 

무기 액터 제작

무기의 별도의 액터로 제작 해 쉽게 확장

무기는 충돌 처리 하지 않게 수정

 

ABWeapon 예제

public:
	UPROPERTY(VisibleAnywhere, Category = Weapon)
		USkeletalMeshComponent* Weapon;
        
// Sets default values
AABWeapon::AABWeapon()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

	Weapon = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WEAPON"));
	RootComponent = Weapon;

	static ConstructorHelpers::FObjectFinder<USkeletalMesh> SK_WEAPON(TEXT("/Game/InfinityBladeWeapons
    /Weapons/Blade/Swords/Blade_BlackKnight/SK_Blade_BlackKnight.SK_Blade_BlackKnight"));
	if (SK_WEAPON.Succeeded())
	{
		Weapon->SetSkeletalMesh(SK_WEAPON.Object);
	}
	//무기는 액세서리로만 사용, 출동 체크 하지 않는다
	Weapon->SetCollisionProfileName(TEXT("NoCollision"));

}

 

ABCharacter에 ABWeapon 생성 및 배치

월드에서 액터 생성 함수는 Getworld->SpawnActor를 이용

생성자에 넣으면 오류가 발생, 모든 클래스가 제대로 생성하지 않은 상태에서 Spawn 할 수 없다

BeginPlay() 에서 동작 하게 한다

#include "ABWeapon.h"
// Called when the game starts or when spawned
void AABCharacter::BeginPlay()
{
	Super::BeginPlay();
	
	//소캣 이름 지정
	FName WeaponSocket(TEXT("hand_rSocket"));
	//SpawnActor 사용 할때는 BeginPlay에서 사용
	//클래스 초기화 부분에 사용 시 아직 클래스 초기화가 정상적으로 이루어지지 않은 상태여서
	//오류를 발생 시킨다.
	auto CurWeapon = GetWorld()->SpawnActor<AABWeapon>(FVector::ZeroVector, FRotator::ZeroRotator);
	if (CurWeapon != nullptr)
	{
		CurWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponSocket);
	}
}