So i have a projectile, fired from a gun (First person shooter Template)
I have also created a “Enemy” actor with a health set on 100
any time i hit the “Enemy” actor it should damage ( for example -25)
Everytime i try to code it unreal engine crashes.
This is my code:
Enemy.h
UCLASS()
class CASTLEDEFENCE_API AEnemy : public AActor{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AEnemy();
UPROPERTY(VisibleAnywhere, BluePrintReadOnly)
float Health = 100;
float GetHealth() const { return Health; }
void SetHealth(float val) { Health = val; }
//.... other code
{
Projectille.h
{
#include "Enemy.h"
//some other code....
UPROPERTY()
AEnemy* EnemyComponent;
}
Projectile.cpp
#include "Projectile.h"
// some code......
void ACastleDefenceProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
if (OtherActor->GetName().Contains("BP_Enemy")) {
EnemyComponent->SetHealth(EnemyComponent->GetHealth() - 25); // this makes the program crash
}
There is most likely a very easy way to solve this but i cannot figure it out.
I’d have to see the crash report to say for sure, but it sounds like EnemyComponent might be a nullptr. I would try something like this:
void ACastleDefenceProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
if (auto Enemy = Cast<AEnemy>(OtherActor))
{
Enemy->SetHealth(Enemy->GetHealth() - 25);
}
{
Thank you so much it worked
I’d have to see the crash report to say for sure
The crash points out to line where i put " //this makes the program crash"
I have a couple of questions:
-
- So if i get this right, if i want to communicate between classes or in this case a blueprint I should use the Cast Method?
-
- And the auto keyword automaticly choses the right Variable Type? I have not seen that before, why cant i just use a float since i know the other Health in the other actor is float ?
I also have created a Health bar above my Enemy in C++ but its not affecting the health bar. Since the code is very simulair to the code above i dont know if i should re-open a new post or ask here.
HealthBar.h (UUserWidget)
//other code...
void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
UPROPERTY(meta = (BindWidget))
UProgressBar* HealthBar;
HealthBar.cpp (UUserWidget)
void UHealthBar::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
HealthBar->SetPercent(50);
the Healthbar in the WidgetBluePrint is set to 10%
once i run the code above it does not set it to 50%
1: I wouldn’t say that the cast method is used to communicate between methods, it just tries to take whatever object you pass in and convert it to the template param (AEnemy in this case). If the conversion is successful, the if statement will evaluate to true. If it fails, then nullptr will be assigned to the Enemy variable and the if statement will evaluate to false.
2: The auto keyword is just shorthand to avoid typing out full class names. In this case, the compiler knows that Cast will only return a Enemny* object, so the compiler sees this and swaps the auto out for AEnemy*.
As far as your healthbar issue, I only really deal with UI in blueprints so I can’t say for sure. It is possible that the UI isn’t set to tick. One thing I would suggest is to set the percent value inside SetHealth (or perhaps binding a function inside the UI to a OnHealthChanged delegate). Setting it every frame inside tick is a bit heavy handed.