본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 22. C++에서 아이템 습득시 사운드 재생하기


목차

  1.  C++에서 사운드 재생하기
  2. 디버그 하기

1. C++에서 사운드 재생하기

 

C++에서 무기를 장착할때 사운드를 재생해보려고 한다.

 

 

void AKnight::EKeyPressed()
{
	AWeapons* OverlappingWeapon = Cast<AWeapons>(OverlappingItem);
	if (OverlappingWeapon)
	{
		OverlappingWeapon->Equip(GetMesh(), FName("RightHandSocket"));
		CharacterState = ECharacterState::ECS_EquippedOneHandWeapon;
		OverlappingItem = nullptr;
		EquippedWeapon = OverlappingWeapon;
	}
	else if (CanDisarm())
	{
		PlayEquipMontage(FName("Unequip"));
		CharacterState = ECharacterState::ECS_Unequipped;
		ActionState = EActionState::EAS_EquippingWeapon;
	}
	else if (CanArm())
	{
		PlayEquipMontage(FName("Equip"));
		CharacterState = ECharacterState::ECS_EquippedOneHandWeapon;
		ActionState = EActionState::EAS_EquippingWeapon;
	}
}

 

캐릭터의 무기를 장착하는 부분의 함수가 존재하고 이 함수를 이용해 소리를 재생하면 된다.

OverlappingWeapon->Equip(GetMesh(), FName("RightHandSocket")); 구문에서 장비를 장착하고 있으므로 이곳에서 사운드를 재생하면 된다.

 

무기 헤더파일로 가보자. 캐릭터 파일이 아닌 무기파일에서 재생하는 이유는 장착 사운드를 무기마다 고유하게 설정할 것이기 때문이다.

 

사운드를 현재 메타사운드로 설정하고 있는데 메타사운드의 타입은 무엇일까?

 

다른 사운드 타입과 동일하게 USoundBase 타입이다.

// 무기.cpp

private:
	UPROPERTY(EditAnywhere, Category = "Weapon Properties")
	USoundBase* EquipSound;

 

무기(매시)별 사운드를 다르게 할 것이기 때문에 EditAnywhere 속성을 집어넣어준다.

 

사운드를 재생하기 위해서는  UGameplayStatics 클래스를 이용할 것이다.

 

언리얼 공식문서에서 찾아보면 이렇게 오버로드된 함수들을 찾을 수 있다.

 

#include "Kismet/GameplayStatics.h"

 

 

문서에 나와있는데로 헤더파일을 include 하자

 

void AWeapons::Equip(USceneComponent* InParent, FName InSocketName)
{
	// 생략
	if (EquipSound)
	{
		UGameplayStatics::PlaySoundAtLocation()
	}
}

 

이제 다음과 같이 사운드를 재생할 수 있다. 함수에 들어가야할 매개변수는 무엇일까?

 

1. WorldContextObject : 사운드를 재생할 월드 컨텍스트이다.

2. Sound : 재생할 사운드 파일

3. Location : 재생할 장소

이하 생략

 

1번의 경우 this를 사용하여 현재 사운드를 사용하고 있는 객체를 나타내어도 해당 객체를 타고 올라가 현재 객체가 존재하는 월드가 어딘지 알 수 있다고 한다. 그렇기 때문에 간단하게 this의 값을 주어도 된다.

 

UGameplayStatics::PlaySoundAtLocation(this, EquipSound, GetActorLocation());

 

이제 이렇게 함수에 매개변수를 넣어주면 된다. 나머지 매개변수는 기본값이 지정되어 있기 때문에 생략해도 된다.

 

이제 컴파일을 하고 무기 블루프린트에서 사운드를 설정한 뒤 사운드가 재생되는지 확인하자.

 

이렇게 하면 재생은 되지만 문제는 무장을 하고 해제할때 소리가 난다. 이 부분을 고쳐야 한다.


2. 디버그 하기

 

다시 비주얼 스튜디오로 돌아가자.

OverlappingItem = nullptr;

 

 해당 버그는 무기가 오버랩 되어 있을때 장착이 끝나면 오버랩된 아이템을 nullptr로 비워두지만 공격을 할경우 다시 무기와 캐릭터가 충돌하여 오버랩된 아이템이 있다고 나와 생기는 문제이다.

 

그렇기 때문에 이 부분을 수정해야 한다. 아이템 헤더 파일로 돌아가자.

 

무기 클래스는 아이템 클래스에 상속 받고 있기 때문에 해당 클래스에 있는 변수를 조금 바꿔야 한다.

 

UPROPERTY(VisibleAnywhere)
USphereComponent* SphereComponent;

 

충돌을 감지하는 스피어 컴포넌트가 현재 프라이빗 영역에 있는데 이를 보호영역으로 옮기면 된다.

 

이제 이 컴포넌트의 충돌을 제거해보자. 무기 cpp로 돌아간다.

 

#include "Components/SphereComponent.h"

void AWeapons::Equip(USceneComponent* InParent, FName InSocketName)
{
	AttachMeshToSocket(InParent, InSocketName);
	if (EquipSound)
	{
		UGameplayStatics::PlaySoundAtLocation(this, EquipSound, GetActorLocation());
	}
    
    // 이 아래부분을 추가한다.
	if (SphereComponent)
	{
		SphereComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}
}

 

이렇게 콜리전을 없애면 한번 장착한 아이템의 스피어컴포넌트에는 콜리전이 없어져 다시 캐릭터와 오버랩 되는 일이 방지된다.