Issue with a UBaseDamage

Hi there i’m having some trouble with the next code:


UCLASS()
class ENVIROMENTMODULE_API UBaseDamage : public UDamageType
{
GENERATED_BODY()

public:
// constructor
UBaseDamage();

UFUNCTION()
	float ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived = 0.f);

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Setup")
	FString Message;

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Setup")
	float Multiplier;

UBaseDamage::UBaseDamage()
{
	bCausedByWorld = true;
	GEngine->AddOnScreenDebugMessage(-1, 4.5f, FColor::Purple, FString::Printf(TEXT("Base Damage INITIALIZED")));
}

float UBaseDamage::ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived)
{
	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("ProcessDamage: %0.0f"), DamageReceived, GetWorld()->TimeSeconds));
	return DamageReceived;
}

on the character:

void ATest1Character::OnTakeDamage(AActor* DamagedActor,float DamageAmount, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
	const UBaseDamage* baseDamage = Cast<UBaseDamage>(DamageType);
	
	if (baseDamage != nullptr)
	{
		HealthPoint -= baseDamage->ProcessDamage(DamagedActor, DamageCauser, DamageAmount);
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f"), DamageAmount, GetWorld()->TimeSeconds));
	}
	else
	{
		HealthPoint -= DamageAmount;
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f - impossibile castare DamageType a <BaseDamage>"), DamageAmount, GetWorld()->TimeSeconds));
	}
}

but i receive the following error:
error C2662: ‘float UBaseDamage::ProcessDamage(AActor *,AActor *,float)’: impossibile convertire il puntatore ‘this’ da ‘const UBaseDamage’ a ‘UBaseDamage &’

Please help

Mark the function as const

float ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived = 0.f) const;

float UBaseDamage::ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived) const

Thanks a lot!
Now i’m having this issue on the function’s call:


Test1Character.cpp.obj : error LNK2019: riferimento al simbolo esterno "__declspec(dllimport) private: static class UClass * __cdecl UBaseDamage::GetPrivateStaticClass(void)" (__imp_?GetPrivateStaticClass@UBaseDamage@@CAPEAVUClass@@XZ) non risolto nella funzione "public: void __cdecl ATest1Character::OnTakeDamage(class AActor *,float,class UDamageType const *,class AController *,class AActor *)" (?OnTakeDamage@ATest1Character@@QEAAXPEAVAActor@@MPEBVUDamageType@@PEAVAController@@0@Z)
Test1Character.cpp.obj : error LNK2019: riferimento al simbolo esterno "__declspec(dllimport) public: float __cdecl UBaseDamage::ProcessDamage(class AActor *,class AActor *,float)const " (__imp_?ProcessDamage@UBaseDamage@@QEBAMPEAVAActor@@0M@Z) non risolto nella funzione "public: void __cdecl ATest1Character::OnTakeDamage(class AActor *,float,class UDamageType const *,class AController *,class AActor *)" (?OnTakeDamage@ATest1Character@@QEAAXPEAVAActor@@MPEBVUDamageType@@PEAVAController@@0@Z)
C:\Users\kvege\OneDrive\Documenti\Unreal Projects\Test1\Binaries\Win64\UnrealEditor-Test1.patch_0.exe : fatal error LNK1120: 2 esterni non risolti

Double check your header definition for OnTakeDamage You might be missing a variable

In cpp

void ATest1Character::OnTakeDamage(AActor* DamagedActor,float DamageAmount, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)

In error

ATest1Character :: OnTakeDamage (class AActor *, float, class UDamageType const *, class AController *, class AActor *)"

In the header definition from the error I don’t see DamageAmount, just float with no variable name (which should match the function in cpp)

OnTakeDamage is called wit no problem, if i remove the baseDamage->ProcessDamage call it’s work… i think it’s only the call stack…

void ATest1Character::OnTakeDamage(AActor* DamagedActor,float DamageAmount, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
const UBaseDamage* baseDamage = Cast(DamageType);

if (baseDamage != nullptr)
{
HealthPoint -= baseDamage->ProcessDamage(DamagedActor, DamageCauser, DamageAmount);
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT(“[TakeDamage] danni: %0.0f”), DamageAmount, GetWorld()->TimeSeconds));
}
else
{
HealthPoint -= DamageAmount;
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT(“[TakeDamage] danni: %0.0f - impossibile castare DamageType a ”), DamageAmount, GetWorld()->TimeSeconds));
}
}

Try this GetPrivateStaticClass() Unresolved External between Modules - #4 by Alex-V

I’ve already successfully compiled the code.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/DamageType.h"
#include "BaseDamage.generated.h"

/**
 * 
 */
UCLASS()
class YOUR_API UBaseDamage : public UDamageType
{
	GENERATED_BODY()

public:
	// constructor
	UBaseDamage();

	UFUNCTION()
		float ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived = 0.f) const;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Setup")
		FString Message;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Setup")
		float Multiplier;

};

.cpp

#include "BaseDamage.h"
#include "Engine/Engine.h"

UBaseDamage::UBaseDamage()
{
	bCausedByWorld = true;
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 4.5f, FColor::Purple, FString::Printf(TEXT("Base Damage INITIALIZED")));
	}
}

float UBaseDamage::ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived) const
{
	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("ProcessDamage: %0.0f"), DamageReceived, GetWorld()->TimeSeconds));
	return DamageReceived;
}

Test1Character.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Test1Character.generated.h"

UCLASS(Blueprintable)
class YOUR_API ATest1Character : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	ATest1Character();

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;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float HealthPoint = 100;


	UFUNCTION(BlueprintCallable)
	void OnTakeDamage(AActor* DamagedActor, float DamageAmount, const  UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser);
};

Character1Test.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "Test1Character.h"
#include "BaseDamage.h"

// Sets default values
ATest1Character::ATest1Character()
{
 	// 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 ATest1Character::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ATest1Character::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ATest1Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}



void ATest1Character::OnTakeDamage(AActor* DamagedActor, float DamageAmount, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
	const UBaseDamage* baseDamage = Cast<UBaseDamage>(DamageType);

	if (baseDamage != nullptr)
	{
		HealthPoint -= baseDamage->ProcessDamage(DamagedActor, DamageCauser, DamageAmount);
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f"), DamageAmount, GetWorld()->TimeSeconds));
	}
	else
	{
		HealthPoint -= DamageAmount;
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f - impossibile castare DamageType a <BaseDamage>"), DamageAmount, GetWorld()->TimeSeconds));
	}
}

Though the cast type fails.

error

I think it should be a passed class of the damage not an instance.

If you want it based on just the class then make these changes:

Ofc need to change the DamageTypeClass in .h too


void ATest1Character::OnTakeDamage(AActor* DamagedActor, float DamageAmount, TSubclassOf<UDamageType> DamageTypeClass, AController* InstigatedBy, AActor* DamageCauser)
{	
	UBaseDamage* baseDamage = DamageTypeClass->GetDefaultObject<UBaseDamage>();
	if (baseDamage != nullptr)
	{
		HealthPoint -= baseDamage->ProcessDamage(DamagedActor, DamageCauser, DamageAmount, GetWorld());
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f"), DamageAmount, GetWorld()->TimeSeconds));
	}
	else
	{
		HealthPoint -= DamageAmount;
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("[TakeDamage] danni: %0.0f - impossibile castare DamageType a <BaseDamage>"), DamageAmount, GetWorld()->TimeSeconds));
	}
}

Changes to damage (needs world context to use without spawning)

float UBaseDamage::ProcessDamage(AActor* Target, AActor* Causer, float DamageReceived, UWorld* WorldContext) const
{
	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT("ProcessDamage: %0.0f"), DamageReceived, WorldContext->TimeSeconds));
	return DamageReceived;
}

I think this is what you want.