Unreal - FootStep Sound.

Overcle·2023년 3월 7일
0

Unreal Study

목록 보기
3/5

알고리즘


캐릭터 움직임 관련 애니메이션에. 발 닿는 부분에 Notify를 추가해.

해당 Notify가 발생될 때 마다 캐릭터 발 아래로 Single Trace를 발사해,

피지컬 머터리얼을 불러와 관련 Particle, Sound를 재생한다.

  • "FootStep" Trace Channel 을 사용하게 되는데 기본값을 Block인 채널이다.

    1. 블렌드 스페이스에 적용했던 각 방향 Animation에 Notify 추가.



기존 초록색으로 추가된거 외로 새로 Notify 추가 FootRight, FootLeft.
각각 애니메이션에 동일하게 추가.

2. AnimInst에 Notify 추가 및 구현


[PlayerAnimInstance.h]

	UFUNCTION()
	void AnimNotify_FootLeft();

	UFUNCTION()
	void AnimNotify_FootRight();
};
[PlayerAnimInstance.cpp]

void UPlayerAnimInstance::AnimNotify_FootLeft()
{
	APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(TryGetPawnOwner());

	if (IsValid(PlayerCharacter))
		PlayerCharacter->FootStep(true);
}

void UPlayerAnimInstance::AnimNotify_FootRight()
{
	APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(TryGetPawnOwner());

	if (IsValid(PlayerCharacter))
		PlayerCharacter->FootStep(false);
}

3. FootStep 관련 코드 구현.

[PlayerCharacter.cpp]

void APlayerCharacter::FootStep(bool Left)
{
	FVector	LineStart;

	if (Left)
		LineStart = GetMesh()->GetSocketLocation(TEXT("Foot_L"));

	else
		LineStart = GetMesh()->GetSocketLocation(TEXT("Foot_R"));

	FVector	LineEnd = LineStart + FVector::DownVector * 50.f;

	FCollisionQueryParams	param(NAME_None, false, this);

	// 충돌 결과로 물리적인 재질 여부를 가지고 올지를 결정한다.
	param.bReturnPhysicalMaterial = true;

	FHitResult	result;
	bool Hit = GetWorld()->LineTraceSingleByChannel(result,
		LineStart, LineEnd, ECollisionChannel::ECC_GameTraceChannel9,
		param);

	if (Hit)
	{
		UUE11PhysicalMaterial* Phys = Cast<UUE11PhysicalMaterial>(result.PhysMaterial);

		if (IsValid(Phys))
		{
			//PrintViewport(1.f, FColor::Blue, TEXT("Phys"));
			//Phys->Play(result.ImpactPoint, result.ImpactNormal);
			if (IsValid(Phys->GetParticle()))
			{
				FActorSpawnParameters	SpawnParam;

				SpawnParam.SpawnCollisionHandlingOverride =
					ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

				AParticleCascade* Particle =
					GetWorld()->SpawnActor<AParticleCascade>(
						result.ImpactPoint, 
						result.ImpactNormal.Rotation(), SpawnParam);

				Particle->SetParticle(Phys->GetParticle());
				Particle->SetSound(Phys->GetSound());
			}

			else if (IsValid(Phys->GetSound()))
			{
				PrintViewport(1.f, FColor::Blue, TEXT("Sound"));
				UGameplayStatics::PlaySoundAtLocation(GetWorld(), Phys->GetSound(), result.ImpactPoint);
			}
		}
	}
}

4. UPhysicalMaterial 생성 및 구현.

1. 모든 클래스 > PhysicalMaterial 클래스로 "UE11PhysicalMaterial" 클래스 생성

2. cpp 부분은 미구현. 생성자만 있을 뿐 공백.

3. h 부분 구현.

[UE11PhysicalMaterial.h]

UCLASS()
class UE11_API UUE11PhysicalMaterial : public UPhysicalMaterial
{
	GENERATED_BODY()
	
public:
	UUE11PhysicalMaterial();

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = true))
	UParticleSystem* mParticle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = true))
	USoundBase* mSound;

public:
	UParticleSystem* GetParticle()	const
	{
		return mParticle;
	}

	USoundBase* GetSound()	const
	{
		return mSound;
	}

5. Particle 클래스 부분 수정.


1. Particle Base.h 함수 오버로딩 추가.

ParticleBase.h
public:
	void SetSound(USoundBase* Sound, bool Play = true);
	virtual void SetParticle(UParticleSystem* Particle);

ParticleBase.cpp

void AParticleBase::SetSound(USoundBase* Sound, bool Play)
{
	if (IsValid(Sound))
	{
		mAudio->SetSound(Sound);

		if (Play)
			mAudio->Play();
	}
}

ParticCascade.h < 이름 잘못생성함.

public:
	virtual void SetParticle(UParticleSystem* Particle);

ParticCascade.cpp

void AParticCascade::SetParticle(UParticleSystem* Particle)
{
	if (IsValid(Particle))
		mParticle->SetTemplate(Particle);
}

6. LandScape에 Physical Material 추가


profile
게임 프로그래머 지망생의 발자취

0개의 댓글