基本的にはデフォルトのTakeDamageが来た時に処理を追加したいのでオーバーライドします。
UE4/Engine/Sounce/Runtime/Engine/Classes/GameFramework/Actor.h
の
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser);
をコピーして
ShooterCharacter.h
にこれをペーストしてoverrideキーワードを追加しました。
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;
ShooterCharacter.cppはこうやって元のSuper::TakeDamegeを追加します
float AShooterCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) ;
{
float DamageApplied = Super::TakeDamage(DamageAmount,DamageEvent,EventInstigator,DamageCauser);
}
次に、ダメージを受けた時のヒットポイントを健康状態のとしてHealth変数を用意します。
ShooterCharacter.h
UPROPERTY(EditDefaultsOnly)
float MaxHealth=100;
UPROPERTY(VisibleAnyWhere)
float Health;
ShooterCharacter.cppでBeginPlayにHealth = MaxHealth;追加
void AShooterCharacter::BeginPlay()
{
Super::BeginPlay();
Health = MaxHealth;
Gun = GetWorld()->SpawnActor<AGun>(GunClass);
GetMesh()->HideBoneByName(TEXT("weapon_r"),EPhysBodyOp::PBO_None );
Gun->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, TEXT("weaponSocket"));
Gun->SetOwner(this);
}
ShooterCharacter.cppでTakeDamageに以下追加
DamageToApply = FMath::Min(Health,DamageToApply);
Health -= DamageToApply;
UE_LOG(LogTemp,Display,TEXT(“Health Left %F”),Health);
float TimeToDisplay =5.0f;
FString Health_str = FString::SanitizeFloat(Health);
(\UE_4.25\Engine\Source\Runtime\Core\Private\Containers\String.cppにある)
FString TestHUDString =TEXT(“Health Left”)+ Health_str;
GEngine->AddOnScreenDebugMessage(-1,TimeToDisplay,FColor::Green,TestHUDString);
(\UE_4.25\Engine\Source\Runtime\Engine\Private\UnrealEngine.cppにある)
詳細は以下
FString | UnrealEngineのドキュメント
return DamageToApply;
float AShooterCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount,DamageEvent,EventInstigator,DamageCauser);
DamageToApply = FMath::Min(Health,DamageToApply);
Health -= DamageToApply;
UE_LOG(LogTemp,Display,TEXT("Health Left %F"),Health);
float TimeToDisplay =5.0;
FString Health_str = FString::SanitizeFloat(Health);
FString TestHUDString =TEXT("Health Left")+ Health_str;
GEngine->AddOnScreenDebugMessage(-1,TimeToDisplay,FColor::Green,TestHUDString);
return DamageToApply;
}
ShooterCharacter.h 全文
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "ShooterCharacter.generated.h"
class AGun;
UCLASS()
class SIMPLESHOOTERCP2_API AShooterCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AShooterCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;
private:
void MoveForward(float AxisValue);
void MoveRight(float AxisValue);
void LockUpRate(float AxisValue);
void LockRightRate(float AxisValue);
void Shoot();
UPROPERTY(EditAnyWhere)
float RotationRate = 10;
UPROPERTY(EditDefaultsOnly)
float MaxHealth=100;
UPROPERTY(VisibleAnyWhere)
float Health;
UPROPERTY(EditDefaultsOnly)
TSubclassOf<AGun> GunClass;
UPROPERTY()
AGun* Gun;
};
ShooterCharacter.cpp 全文
// Fill out your copyright notice in the Description page of Project Settings.
#include "ShooterCharacter.h"
#include "Gun.h"
//#include "Engine/Engine.h"
// Sets default values
AShooterCharacter::AShooterCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AShooterCharacter::BeginPlay()
{
Super::BeginPlay();
Health = MaxHealth;
Gun = GetWorld()->SpawnActor<AGun>(GunClass);
GetMesh()->HideBoneByName(TEXT("weapon_r"),EPhysBodyOp::PBO_None );
Gun->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, TEXT("weaponSocket"));
Gun->SetOwner(this);
}
// Called every frame
void AShooterCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AShooterCharacter::Shoot()
{
Gun->PullTrigger();
}
// Called to bind functionality to input
void AShooterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent ->BindAxis(TEXT("MoveForward"),this,&AShooterCharacter::MoveForward);
PlayerInputComponent ->BindAxis(TEXT("LockUp"),this,&APawn::AddControllerPitchInput);
PlayerInputComponent ->BindAxis(TEXT("MoveRight"),this,&AShooterCharacter::MoveRight);
PlayerInputComponent ->BindAxis(TEXT("LockRight"),this,&APawn::AddControllerYawInput);
PlayerInputComponent ->BindAxis(TEXT("LockUpRate"),this,&AShooterCharacter::LockUpRate);
PlayerInputComponent ->BindAxis(TEXT("LockRightRate"),this,&AShooterCharacter::LockRightRate);
PlayerInputComponent ->BindAction(TEXT("Jump"),EInputEvent::IE_Pressed,this,&ACharacter::Jump);
PlayerInputComponent ->BindAction(TEXT("Shoot"),EInputEvent::IE_Pressed,this,&AShooterCharacter::Shoot);
}
float AShooterCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount,DamageEvent,EventInstigator,DamageCauser);
DamageToApply = FMath::Min(Health,DamageToApply);
Health -= DamageToApply;
UE_LOG(LogTemp,Display,TEXT("Health Left %F"),Health);
float TimeToDisplay =5.0f;
FString Health_str = FString::SanitizeFloat(Health);
FString TestHUDString =TEXT("Health Left")+ Health_str;
GEngine->AddOnScreenDebugMessage(-1,TimeToDisplay,FColor::Green,TestHUDString);
return DamageToApply;
}
void AShooterCharacter::MoveForward(float AxisValue)
{
AddMovementInput(GetActorForwardVector() * AxisValue);
}
void AShooterCharacter::MoveRight(float AxisValue)
{
AddMovementInput(GetActorRightVector() * AxisValue);
}
void AShooterCharacter::LockUpRate(float AxisValue)
{
AddControllerPitchInput(AxisValue * RotationRate * GetWorld()->GetDeltaSeconds());
}
void AShooterCharacter::LockRightRate(float AxisValue)
{
AddControllerYawInput(AxisValue * RotationRate * GetWorld()->GetDeltaSeconds());
}
// void AShooterCharacter::LockUp(float AxisValue)
// {
// AddControllerPitchInput(AxisValue);
// }
こうなった。