可能很多初学者如果想知道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的伤害系统。