Hit Reaction Animation
Рекомендую досмотреть до лекции 155. В ней мы рассматриваем как наносить различный ущерб для различных частей тела. Это первый шаг.
Чтобы получить эффект физической реакции при попадании патрона, можно включить физическую симуляцию относительно кости в скелетe и установить блендинг по кости в какое-нибудь значение (например, в 0.7 и на таймере вернуть блендинг в 0.0 ). В финальный код нашего проекта в USTUHealthComponent нужно добавить следующее (указатели не проверяю в данном коде, чтобы не усложнять):
.h файл
private:
float CurrentHitBlend = 0.0f;
FTimerHandle HitReactTimer;
FName CurrentBoneName;
void StartPhysReaction(const FName& BoneName, const FVector& ShotFromDirection);
void UpdateSimulation();
void StopCurrentBoneSimulation();
.cpp файл
void USTUHealthComponent::OnTakePointDamage(AActor* DamagedActor, float Damage, class AController* InstigatedBy, FVector HitLocation,
class UPrimitiveComponent* FHitComponent, FName BoneName, FVector ShotFromDirection, const class UDamageType* DamageType,
AActor* DamageCauser)
{
const auto FinalDamage = Damage * GetPointDamageModifier(DamagedActor, BoneName);
ApplyDamage(FinalDamage, InstigatedBy);
StartPhysReaction(BoneName, ShotFromDirection);
}
void USTUHealthComponent::StartPhysReaction(const FName& BoneName, const FVector& ShotFromDirection)
{
const auto Character = Cast<ACharacter>(GetOwner());
if (!CurrentBoneName.IsNone())
{
StopCurrentBoneSimulation();
}
CurrentHitBlend = 0.7f; // how much 0..1
CurrentBoneName = BoneName;
const float ImpulseMagnitude = 500.0f;
Character->GetMesh()->SetAllBodiesBelowSimulatePhysics(CurrentBoneName, true);
Character->GetMesh()->SetAllBodiesBelowPhysicsBlendWeight(CurrentBoneName, CurrentHitBlend);
Character->GetMesh()->AddImpulseToAllBodiesBelow( ImpulseMagnitude * ShotFromDirection, CurrentBoneName, true);
const float TimerRate = 0.003f;
GetWorld()->GetTimerManager().ClearTimer(HitReactTimer);
GetWorld()->GetTimerManager().SetTimer(HitReactTimer, this, &USTUHealthComponent::UpdateSimulation, TimerRate, true);
}
void USTUHealthComponent::UpdateSimulation()
{
CurrentHitBlend -= 0.01f;
if (CurrentHitBlend <= 0.0f)
{
GetWorld()->GetTimerManager().ClearTimer(HitReactTimer);
StopCurrentBoneSimulation();
}
else
{
const auto Character = Cast<ACharacter>(GetOwner());
Character->GetMesh()->SetAllBodiesBelowPhysicsBlendWeight(CurrentBoneName, CurrentHitBlend);
}
}
void USTUHealthComponent::StopCurrentBoneSimulation()
{
CurrentBoneName = NAME_None;
const auto Character = Cast<ACharacter>(GetOwner());
Character->GetMesh()->SetAllBodiesBelowSimulatePhysics(CurrentBoneName, false);
Character->GetMesh()->SetAllBodiesBelowPhysicsBlendWeight(CurrentBoneName, 0.0f);
}
Также мешу через функцию SetCollisionEnabled
или в блюпринте необходимо указать ECollisionEnabled::QueryAndPhysics
Last updated
Was this helpful?