MiddleКодЧастоЕщё не отвечали
Реализуйте нанесение урона при столкновении двух Actor'ов в Unreal Engine.
Actor-снаряд должен наносить урон тому, во что попадает. Привяжите обработчик к делегату удара компонента столкновений и направьте урон через штатный конвейер урона движка, чтобы исход решал получающий Actor.
Требования:
у цели) — не вычитайте здоровье жертвы напрямую из снаряда.
- Наносите урон через
UGameplayStatics::ApplyDamage(он вызываетTakeDamage - Игнорируйте попадания в себя и в собственного владельца/instigator снаряда.
- Передавайте instigator controller, чтобы корректно засчитывалось авторство убийства.
Допишите привязанный обработчик удара:
void AProjectile::OnHit(UPrimitiveComponent*, AActor* OtherActor,
UPrimitiveComponent*, FVector, const FHitResult& Hit)
{
// ваш код здесь: отсеките попадания в себя/владельца, затем направьте урон в OtherActor
}
Допишите реализацию.
Привяжите обработчик к делегату OnComponentHit или OnComponentBeginOverlap компонента столкновений, затем направьте урон через UGameplayStatics::ApplyDamage. Это вызовет TakeDamage у цели, оставляя логику урона на получателе, а не на снаряде.
- ✗Опрашивать перекрытия в
Tickвместо привязки делегата столкновений - ✗Вычитать здоровье напрямую вместо маршрутизации через
ApplyDamage/TakeDamage - ✗Забывать проверить, что задетый Actor не является владельцем снаряда
- →В чём разница между событием Hit и событием Overlap?
- →Почему направлять урон через
ApplyDamage, а не через вызов своего интерфейса?
Урон при столкновении снаряда
// Projectile.h
UCLASS()
class AProjectile : public AActor
{
GENERATED_BODY()
public:
AProjectile();
protected:
UPROPERTY(VisibleAnywhere)
USphereComponent* CollisionComp;
UPROPERTY(EditDefaultsOnly)
float Damage = 25.f;
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, FVector NormalImpulse,
const FHitResult& Hit);
};
// Projectile.cpp
AProjectile::AProjectile()
{
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("Collision"));
RootComponent = CollisionComp;
// Привязка обработчика — конструктор только подписывает делегат
CollisionComp->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
}
void AProjectile::OnHit(UPrimitiveComponent*, AActor* OtherActor,
UPrimitiveComponent*, FVector, const FHitResult& Hit)
{
// Не бить самого себя и не бить владельца-стрелка
if (!OtherActor || OtherActor == this || OtherActor == GetOwner())
{
return;
}
AController* InstigatorController =
GetInstigator() ? GetInstigator()->GetController() : nullptr;
// Урон маршрутизируется на получателя — его TakeDamage решает исход
UGameplayStatics::ApplyDamage(OtherActor, Damage,
InstigatorController, this,
UDamageType::StaticClass());
Destroy();
}
ApplyDamage вызывает OtherActor->TakeDamage(...), поэтому логика реакции на урон живёт на цели (например, в её UHealthComponent), а не дублируется в каждом снаряде.