캐릭터 움직임 관련 애니메이션에. 발 닿는 부분에 Notify를 추가해.
해당 Notify가 발생될 때 마다 캐릭터 발 아래로 Single Trace를 발사해,
피지컬 머터리얼을 불러와 관련 Particle, Sound를 재생한다.
"FootStep" Trace Channel 을 사용하게 되는데 기본값을 Block인 채널이다.
기존 초록색으로 추가된거 외로 새로 Notify 추가 FootRight, FootLeft.
각각 애니메이션에 동일하게 추가.
[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);
}
[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);
}
}
}
}
[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;
}
public:
void SetSound(USoundBase* Sound, bool Play = true);
virtual void SetParticle(UParticleSystem* Particle);
void AParticleBase::SetSound(USoundBase* Sound, bool Play)
{
if (IsValid(Sound))
{
mAudio->SetSound(Sound);
if (Play)
mAudio->Play();
}
}
public:
virtual void SetParticle(UParticleSystem* Particle);
void AParticCascade::SetParticle(UParticleSystem* Particle)
{
if (IsValid(Particle))
mParticle->SetTemplate(Particle);
}