소켓을 활용한 무기 장착하기

유영준·2023년 1월 12일
0
post-thumbnail

오늘은 무기 액터를 제작하고, 이를 캐릭터 소켓에 부착할 것이다

사용한 무기 에셋은 링크를 통해 다운로드 가능하다


소켓 위치 조정하기

캐릭터의 스켈레탈 메쉬에는 hand_rSocket 이라는 무기를 장착하기 위한 소켓이 존재한다

hand_rSocket을 우클릭 후 Add preview Asset 을 통해 에셋이 어떻게 보일지 적용할 수 있다

이후 hand_rSocket 의 위치를 조절하여 캐릭터가 자연스럽게 잡고 있는 모습을 보이도록 하자

나의 경우에는 무기는 heroSword11을 사용했고, 소켓의 위치는 (-7.5, 4.8, 0.6), 회전은 (18.4, 23.2, 83.0) 을 적용했다

(애니메이션도 확인하며 최적의 값을 찾도록 하자)


무기 액터 구현

소켓을 완성했다면, 무기를 하나의 액터를 통해 구현하도록 하겠다

이 방법으로 구현하게 되면, 추후 무기를 교체하거나 하는 등의 구현이 훨씬 쉬워진다

헤더 파일에 스켈레탈 메쉬 포인터 변수 Weapon 을 선언해주자

ABWeapon.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "ArenaBattle.h"
#include "GameFramework/Actor.h"
#include "ABWeapon.generated.h"

UCLASS()
class ARENABATTLE_API AABWeapon : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AABWeapon();

	UPROPERTY(VisibleAnywhere, Category = Weapon)
	USkeletalMeshComponent* Weapon;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

이를 cpp 파일에서 구현해주도록 하겠다

ABWeapon.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "ABWeapon.h"

// 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_HeroSword11/SK_Blade_HeroSword11.SK_Blade_HeroSword11"));

	if (SK_WEAPON.Succeeded())
		Weapon->SetSkeletalMesh(SK_WEAPON.Object);

	Weapon->SetCollisionProfileName(TEXT("NoCollision"));
}

// Called when the game starts or when spawned
void AABWeapon::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AABWeapon::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

이때 무기의 Collision 타입은 NoCollision 으로 설정해주자

(NoCollision 타입의 설정값)

이제 ABCharacter.cpp 파일에서 무기 액터를 찾아 hand_rSocket에 추가해주도록 하자

ABCharacter.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "ABCharacter.h"
#include "ABAnimInstance.h"
#include "DrawDebugHelpers.h"
#include "ABWeapon.h"

...

// Called when the game starts or when spawned
void AABCharacter::BeginPlay()
{
	Super::BeginPlay();

	FName WeaponSocket(TEXT("hand_rSocket"));
	auto CurWeapon = GetWorld()->SpawnActor<AABWeapon>(FVector::ZeroVector, FRotator::ZeroRotator);
	if (nullptr != CurWeapon)
		CurWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, WeaponSocket);

}

...

이때 언리얼 엔진 라이프 사이클을 참고하여 Weapon 액터가 생성 전 탐색을 하지 않도록 탐색 과정을 BeginPlay 함수에 넣어주었다

(완성된 장면)

profile
토비폭스가 되고픈 게임 개발자

0개의 댓글