可能很多初學者如果想知道UE4的這種傷害系統如何使用起來會有點迷茫。
我自己做了demo給大家參考下。
首先要有個子彈類。
.h代碼如下

1 UCLASS() 2 class SNVRCLAYSHOOTING_API AProjectile : public AActor 3 { 4 GENERATED_BODY() 5 6 public: 7 // Sets default values for this actor's properties 8 AProjectile(); 9 10 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Projectile") 11 UStaticMeshComponent* ProjectileMesh; 12 13 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Projectile") 14 UParticleSystemComponent* LaunchParticle; //煙火,開槍時 15 16 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Projectile") 17 UProjectileMovementComponent *ProjectileMovementComponent = nullptr; 18 19 protected: 20 // Called when the game starts or when spawned 21 virtual void BeginPlay() override; 22 23 UFUNCTION() 24 void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit); 25 26 public: 27 // Called every frame 28 virtual void Tick(float DeltaTime) override; 29 30 UFUNCTION(BlueprintCallable, Category = "Projectile_Fun") 31 void LaunchProjectile(FVector Speed); 32 33 };
.cpp代碼如下

1 AProjectile::AProjectile() 2 { 3 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 4 PrimaryActorTick.bCanEverTick = true; 5 6 ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(FName("ProjectileMovement")); //生成組件 7 ProjectileMovementComponent->bAutoActivate = false; //自動飛行調成false 8 9 ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(FName("ProjectileMesh")); 10 RootComponent = ProjectileMesh; 11 ProjectileMesh->SetNotifyRigidBodyCollision(true); 12 ProjectileMesh->SetVisibility(true); 13 14 LaunchParticle = CreateDefaultSubobject<UParticleSystemComponent>(FName("LaunchParticle")); 15 LaunchParticle->SetupAttachment(ProjectileMesh); //將粒子效果綁定在根結點上(即ProjectileMesh) 16 LaunchParticle->SetAutoActivate(true); //創建好就啟動 17 18 ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit); 19 20 InitialLifeSpan = 5.0f; 21 } 22 23 // Called when the game starts or when spawned 24 void AProjectile::BeginPlay() 25 { 26 Super::BeginPlay(); 27 28 } 29 30 // Called every frame 31 void AProjectile::Tick(float DeltaTime) 32 { 33 Super::Tick(DeltaTime); 34 35 } 36 void AProjectile::LaunchProjectile(FVector Speed) 37 { 38 ProjectileMovementComponent->SetVelocityInLocalSpace(Speed); 39 ProjectileMovementComponent->Activate(); //可以飛行了 40 } 41 //碰撞后發生的事件 42 void AProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) 43 { 44 UE_LOG(LogTemp, Warning, TEXT("AProjectile::OnHit--OtherActor.Name=%s"),*OtherActor->GetName()); //撞擊后給個提示 45 46 ProjectileMesh->SetNotifyRigidBodyCollision(false); //碰撞之后再也不發生碰撞事件 47 //CollisionMesh->DestroyComponent(); //不是DestroyActor,Component是單一一個 48 49 //受傷害源OtherActor的TakeDamage()會被調用 50 UGameplayStatics::ApplyPointDamage(OtherActor, 10.0f, GetActorLocation(), Hit,NULL,NULL, UDamageType::StaticClass()); 51 52 Destroy(); 53 }
傷害的入口從OnHit看出,調用了UGameplayStatics::ApplyPointDamage;
第一個參數就是受傷害源,UE4的傷害系統會調用受傷害源的TakeDamege接口;
此時子彈有了傷害力,那么受傷害源就要被傷害;
每個actor都有這個接口virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser);
只要重寫這個接口,寫上自己的處理邏輯。
受傷害源部分代碼如下:

1 float ADamagedActor::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) 2 { 3 float actuallyApplied = 0.0f; 4 5 MaxHP -= DamageAmount; 6 7 UE_LOG(LogTemp,Warning,TEXT("ADamagedActor::TakeDamage--MaxHP=%f"),MaxHP); 8 9 actuallyApplied = FMath::Clamp<float>(MaxHP, 0.0f, 100.0f); 10 11 return actuallyApplied; 12 }
以上就是簡單的使用UE4的傷害系統。