오늘은 무기 액터를 제작하고, 이를 캐릭터 소켓에 부착할 것이다
사용한 무기 에셋은 링크를 통해 다운로드 가능하다
캐릭터의 스켈레탈 메쉬에는 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
함수에 넣어주었다
(완성된 장면)