728x90
이 글은 Inflearn - Rookiss : 언리얼 엔진4 입문 강의를 듣고 정리한 글입니다.

 

목차.

  1. 서론
  2. 오브젝트 채널, 프로파일 추가
  3. 프로파일 추가
  4. C++ 클래스 코드 수정
  5. 결과

 

서론

 

플레이어와 상호 작용하는 아이템은 많은 게임들의 핵심 요소입니다.

예를 들어 RPG 게임에서 아이템이 드랍되고 캐릭터가 아이템에 접촉하면 획득하는 것처럼

무기가 바닥에 있고 캐릭터가 무기와 접촉했을 때 그 무기를 장착하는 기능을 구현해 보겠습니다.

 

오브젝트 채널 추가

 

먼저 오브젝트 채널을 추가해야합니다.

 

무기에 적용될 오브젝트 채널을 추가하겠습니다.

 

프로젝트 세팅 -> 콜리전 -> 새 오브젝트 채널을 선택하고 이름은 MyCollectible,

기본 반응은 충돌을 하면 안 되기 때문에 Ignore로 해주겠습니다.

 

오브젝트-채널-추가
오브젝트 채널 추가

 

프로파일 추가

 

새로 추가한 오브젝트 채널을 용도에 맞게 규칙을 설정해 주겠습니다.

 

프로파일 편집 창을 보면 기본 반응을 Ignore로 설정했기 때문에 전부다 무시로 체크되어있습니다.

 

MyCollectible-프로파일-편집
프로파일-편집

 

콜리전은 충돌하지 않고 정보만 받아오면 되기 때문에 Query Only로,

오브젝트 유형은 아까 생성한 MyCollectible로, 다른 트레이스와 오브젝트들은 모두 무시로 하고 MyCharacter만 충돌 가능하게 겹침으로 해주었습니다.

 

저번 글에서 말했던 것처럼 한 방향에서만 프로파일을 설정해선 안되고 반대 방향에서도 동일하게 설정해줘야 합니다.

 

MyCollectible-> MyCharacter를 겹침으로 해주었으니

반대로 MyCharacter -> MyCollectible도 겹침으로 설정해 줬습니다.

 

MyCharacter-프로파일-편집
MyCharacter 프로그파일 편집

 

C++ 클래스 코드 수정

 

 

Box 컴포넌트 활용해서 충돌 체크를 해줄 것입니다.

 

MyWeapon.h

....
public:
    UPROPERTY(VisibleAnywhere)
    class UBoxComponent* Trigger;
}

 

Trigger를 제외한 다른 코드는 생략하였습니다.

트리거는 웨폰에 붙여주었는데 안 붙이면 무기가 이동하더라도 트리거 컴포넌트는 이동하지 않을 수 있기 때문입니다.

 

MyWeapon.cpp

#include "Components/BoxComponent.h"
#include "MyCharacter.h"

AMyWeapon::AMyWeapon()
{
....
	Trigger = CreateDefaultSubobject<UBoxComponent>(TEXT("TRIGGER"));
	Trigger->SetupAttachment(Weapon);
	Trigger->SetCollisionProfileName(TEXT("MyCollectible"));
	Trigger->SetBoxExtent(FVector(30.f, 30.f, 30.f));
}

 

이 상태로 게임을 실행해 보면 다음과 같은 계층구조로 인스턴스가 잘 생성되는 것을 볼 수 있습니다.

 

계층구조-인스턴스-생성
계층구조 인스턴스 생성

 

이대로는 캐릭터와 Trigger박스가 충돌해도 아무런 이벤트가 발생하지 않습니다.

 

무기가 캐릭터의 Socket에 장착되도록 코드를 추가해 주겠습니다.

 

MyWeapon.h

protected:
....
	virtual void PostInitializeComponents();
private:
	UFUNCTION()
	void OnCharacterOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

 

OnCharacterOverlap이라는 함수를 이용하는데 인자가 정말 많고 긴 것 같습니다.

아직은 잘 모르겠지만 이름을 통해서 어느 정도 유추해 볼 수 있습니다.

 

MyWeapon.cpp

void AMyWeapon::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	Trigger->OnComponentBeginOverlap.AddDynamic(this, &AMyWeapon::OnCharacterOverlap);
}
void AMyWeapon::OnCharacterOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Log, TEXT("Overlapped"));

	AMyCharacter* MyCharacter = Cast<AMyCharacter>(OtherActor);
	if (MyCharacter)
	{
		FName WeaponSocket(TEXT("hand_l_socket"));
		AttachToComponent(MyCharacter->GetMesh(),
		FAttachmentTransformRules::SnapToTargetNotIncludingScale,
		WeaponSocket);
	}
}

 

OnComponentBeginOverlap은 두 컴포넌트가 서로 겹칠 때 발생하고 델리게이트를 사용해서 지정한 함수가 호출되게 했습니다.

 

OnCharacterOverlap 함수를 사용했는데 아직 이해하기 어려운 부분이 많은 것 같습니다.

아마 흐름을 보았을 때 OnComponentBeginOverlap 사용해 이벤트가 발생하면 OnCharacterOverlap에 다양한 정보들을 전달해 주는 것 같습니다.

 

여기서 알 수 있는 것은 델리게이트가 아무한테 연결시켜 줄 수 있고, 어느 정도 함수에 대한 규칙이 있다는 점입니다.

 

그렇게 충돌한 다른 액터의 정보를 AMyCharacter로 캐스팅해주고 캐스팅에 성공했다면

hand_l_socket에 AttackToComponent 해줍니다.

 

결과

 

컴파일 후 무기(Actor)를 레벨에 배치한 뒤 캐릭터와 충돌시켜 보면 

캐릭터 손에 무기가 장착되는 것을 볼 수 있습니다.

 

무기를 4개 먹으니 4개의 무기가 장착되었습니다.

무기-장착-모습
무기가 잘 장착되는 모습

 

지금까지 오브젝트 채널 추가, 프로파일 편집, c++ 클래스를 이용한 이벤트 발생을 했습니다.

 

728x90

+ Recent posts