Download

How to put DamageType in switch statement?

I have several DamageTypes. I want to do something special for Character depending on what DamageType have taken.

Now I use this code for solve my problem. But I don’t want to use IF statements + casting!


 float ABaseCharacter::TakeDamage(float Damage, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
 {
 
     UDamageType *DamageType = Cast<UMyDamageType1>(DamageEvent.DamageTypeClass->GetDefaultObject());
     if (DamageType){
         //do something
 
     }
 
     DamageType = Cast<UMyDamageType2>(DamageEvent.DamageTypeClass->GetDefaultObject());
 
     if (DamageType){
         //do something
 
     }
 // and there will be many same code (copy-paste) because 
 // I need to find what DamageType I got.
     return Damage;
 }

Is there more elegant solution?

Simple answer is not really. If you want a switch you’d have to put an Int based type inside the base damage type class or a single subclass.

Okay, for example I have 3 classes Dtype1,Dtype2,Dtype3
Each class have public int field which identify class.
In TakeDamage I receive DamageEvent and I don’t know what type is it. I can write something like:


float ABaseCharacter::TakeDamage(float Damage, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
 {
  auto DamageVarible = DamageEvent.DamageTypeClass->GetDefaultObject()); // I got the object reference. But I can't get field from it because it need casting in type, which I don't know.

 }

So the field in class does not help to identify it.
I don’t know how this help me. Can you explain?

Hey you can do something like this, to get the Base class and then check the class type.
e.g:


	UDamageType* DmgType = Cast<UDamageType>(DamageEvent.DamageTypeClass->GetDefaultObject());
	if (DmgType)
	{
		// Switch or else if statments.
		if (DmgType->IsA(USomeDamageType::StaticClass()))
		{

		}
		else if (DmgType->IsA(USomeOtherDamageType::StaticClass()))
		{

		}
	}

Also you can get it directly like this.


	USomeDamageType* DmgType = DamageEvent.DamageTypeClass->GetDefaultObject<USomeDamageType>();

Hope it helps.
WCode

Do you know, is it possible to get field’s value from DamageVarible?


float ABaseCharacter::TakeDamage(float Damage, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
 {
  auto DamageVarible = DamageEvent.DamageTypeClass->GetDefaultObject()); // I got the object reference. But I can't get field from it because it need casting in type, which I don't know.

 }

If i can automatically cast or receive by TakeDamage the object of class from which I can get field’s value…

Ok i don`t understand what you mean by that.

Are you trying to access propertys spesific to a UDamageType without casting it?

Yes! Is it possible if I don’t know type?

What I would do is create a MyDamageClass which has an int in it that tells you what type it is. Then for your actual damage types, use this MyDamageClass as a parent. You should then be able to do something like

UMyDamageClass * dmg = Cast <UMyDamageClass> ( GivenObject);

and then call dmg->MyType as part of a switch.

Well with out casting to atleast a base class I will say no.
How ever when debugging I did see the members for the damage type in ClassDefaultObject member.
So the data is there somewhere in memory, but if you can safely access it i have no idea.
*
I think a better method is having your Damage types derived from one class.
With some virtual methods in them, so you don`t have to worry about the type.

Just have your class do its own thing and all you do is call the method`s.*

Thanks all. I’v solved my problem my use polymorphysm. I create virtual function in base class. And override it in derived classes. Then I can easily access to it by using:


UMyBaseDamageType *DamageType = Cast<UMyBaseDamageType>(DamageEvent.DamageTypeClass->GetDefaultObject());
 
DamageType->ProcessDamage();

And the ProcessDamage() implementation depends on which class I’v received from DamageEvent