오늘부터는 무기와 공격에 대해 배워보고 이를 실제로 만들어보자

 

일단 전에 추가해준 무기에 Box Collision을 추가하여 칼날에 충돌하는 것을 감지할 수 있도록 하자 그리고 

여기에 칼의 시작과 끝 포인트를 Scene Component로 지정하여 칼날의 시작부분부터 끝부분까지 Trace

하면서 Collision이벤트를 감지할 수 있도록 하자.

 

Weapon.h

	class UBoxComponent;
    
private:
    UPROPERTY(VisibleAnywhere, Category = "Weapon Properties")
	UBoxComponent* WeaponBox;

Weapon.cpp

AWeapon::AWeapon()
{
	WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponBox"));
	WeaponBox->SetupAttachment(GetRootComponent());
}

 

 

그리고 무기의 Box Collision의 콜리전 설정을 Custom으로 바꿔서 Pawn 클래스는 무시하도록 설정하여 자신의 캐릭터에는 이벤트가 발생하지않도록 하는 등의 세부설정을 조절할 수 있게하자

그리고 만들어둔 캐릭터 BP를 가지고 테스트하는데 이렇게 월드에 생긴 인스턴스의 Type을 WorldDynamic으로 바꾸고 Collision만을 조정하여 테스트할 수 있다. 

이렇게 해주게되면 Collision이벤트가 정상적으로 발생한다.

이것을 코드로 구현해보자 

일단 필요한 것은 Collision가 일어날 때 사용될 콜백 함수와 Start End 씬컴포턴트이다.

콜백함수를 BeginPlay에서 지정해주고 

콜백함수에서는 Start End를 가지고 UKismetSystemLibrary::BoxTraceSingle 함수를 사용하여 Box Collision이 발생하는

부분을 보여줄 수 있도록 하자.

Weapon.h

	UFUNCTION()
	void OnBoxOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    
    
	UPROPERTY(VisibleAnywhere)
	USceneComponent* BoxTraceStart;

	UPROPERTY(VisibleAnywhere)
	USceneComponent* BoxTraceEnd;

 

Weapon.cpp

AWeapon::AWeapon()
{
	BoxTraceStart = CreateDefaultSubobject<USceneComponent>(TEXT("Box Trace Start"));
	BoxTraceStart->SetupAttachment(GetRootComponent());

	BoxTraceEnd = CreateDefaultSubobject<USceneComponent>(TEXT("Box Trace End"));
	BoxTraceEnd->SetupAttachment(GetRootComponent());
}

}
void AWeapon::BeginPlay()
{
	Super::BeginPlay();

	WeaponBox->OnComponentBeginOverlap.AddDynamic(this, &AWeapon::OnBoxOverlap);
}

void AWeapon::OnBoxOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	const FVector Start = BoxTraceStart->GetComponentLocation();
	const FVector End = BoxTraceEnd->GetComponentLocation();

	TArray<AActor*> ActorsToIgnore;
	ActorsToIgnore.Add(this);
	FHitResult BoxHit;

	UKismetSystemLibrary::BoxTraceSingle(
		this,
		Start,
		End,
		FVector(5.f, 5.f, 5.f),
		BoxTraceStart->GetComponentRotation(),
		ETraceTypeQuery::TraceTypeQuery1,
		false,
		ActorsToIgnore,		//무시할거
		EDrawDebugTrace::ForDuration,
		BoxHit,
		true		//자신무시
	);
}

 

이때 Start와 End Scene Component는 위치를 시작과 끝점으로 조정해주어야한다.

 

이렇게 해주게 되면 정상적으로 Collision이벤트가 작동한다.

 

이제 이 box Collision  이벤트가 공격할 때만 작동하도록 하자 일단 Collision의 시작과 끝을 인식할 수 있도록 attack_montage에 Notify를 추가해주자

 

그리고 코드상에서 무기의 Collision을 바꿔주는 함수를 Character클래스에서 작성해주자

먼저 Collision Box를 가져올 수 있도록 get함수를 정의해주자

Weapon.h

public:
	FORCEINLINE UBoxComponent* GetWeaponBox() const { return WeaponBox; }

 

SlashCharacter.cpp

void ASlashCharacter::SetWeaponCollisionEnabled(ECollisionEnabled::Type CollisionEnabled)
{
	if (EquippedWeapon && EquippedWeapon->GetWeaponBox())
	{
		EquippedWeapon->GetWeaponBox()->SetCollisionEnabled(CollisionEnabled);
	}
}

 

이제 블루프린트로 돌아가서 노티파이 이벤트함수에 우리가 만들어준 함수를 붙이자

 

이렇게 해주면 이제 공격할때만 Collision Box가 생성된다.

 

이제 공격을 했을 때 기능을 구현해야하는데 이때 인터페이스 기능을 사용하여 구현해보자 

인터페이스는 쉽게 말하자면 껍대기만 가지고 있는 상위 클래스라고 보면 된다. 하위 클래스는 이 클래스를 

상속받아서 세부기능을 원하는대로 정의하면 된다.

 

언리얼에서는 이러한 기능을 Unreal Interface라는 클래스를 통해 제공해준다. 

 

 

이렇게 생성한 코드를 보면 클래스가 2개있는 것을 볼 수 있는데 이는 언리얼엔진의 리플렉션 시스템과 연관이 있는 것으로 위의 클래스를 통해 리플랙션 시스템이 연결되고 밑의 클래스를 통해 우리가 기능 껍대기를 만들어주게 된다.

HitInterface.h

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

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "HitInterface.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UHitInterface : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class SLASH_API IHitInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
};

+ Recent posts