Able Ability System Info and Support Thread

Ah, yea. The “Events” aren’t events in the BP sense. They’re merely methods that are called. So, all Custom Events come through the OnCustomEvent callback. You can use the name parameter to define which event is doing the calling, that’s the entire purpose of that parameter.

Actual BP event creation based on a Task name would be a bit tricky (but it might be do-able, haven’t looked into it honestly).

Ok, thanks. That clears it up a bit. Still have no idea how to trigger an actual BP custom event from that function override (that probably has to do something with me being not so enlightened). It says that I can’t use reference to self in a custom event and fails to compile

Able v2.23 Submitted

Notes:

I updated the plugin from the launcher to the 4.19.2 binary engine after getting notified of an update available. Copied over the plugin directory to my source build. Compiled successfully.

Went over to my project. Deleted the Intermediate and Binaries directories (habit after I recompile the engine). It compiles with no error. Try to run the editor and I get an error of


**LogModuleManager: Warning: Found module file ../../../Engine/Plugins/Able/Binaries/Win64/UE4Editor-Able.dll (API version 3944462), but it was incompatible with the current engine API version (0). This is likely a stale module that must be recompiled.**
LogModuleManager: Display: Found up-to-date module file ../../../Engine/Plugins/Able/Binaries/Win64/UE4Editor-AbleCore.dll (API version 0).
LogModuleManager: Display: Found up-to-date module file ../../../Engine/Plugins/Able/Binaries/Win64/UE4Editor-AbleEditor.dll (API version 0).

This is the first time applying an updated plugin. I tried searching to see if I needed to do something else but so far not finding anything.

All good now. I deleted the UE4Editor-Able.dll and recompiled. The other dll’s compiled so I assumed the one in error did to. It didn’t.

I had a bug report come in on email with a crash related to Animation Interrupts, it’s a stupid error on my part and I’ll get a fix out - but in the meantime, if you want to apply the change locally you can:

AnimNode_AbilityAnimationPlayer.cpp

Sorry for the hiccup.

Edit: Solved. GeneratedClass is the answer. I was simply casting incorrectly.

Is there a way to get a BlueprintGeneratedClass from a UBlueprint that is a UAblAbility?

When using TSubclassOf<UAblAbility> in a UDataTable, the entry can look like:


BlueprintGeneratedClass'Game/Player/Reactions/ABL_Flinch.ABL_Flinch_C'

Is it possible to get this in C++ from a UBlueprint?

Something along the lines of what I’ve tried so far is:


UBlueprint* FlinchBlueprint = GetFlinchBlueprint();
TSubclassOf<UAblAbility> Flinch = Cast<UAblAbility>(FlinchBlueprint)->GetClass();

or


UBlueprint* FlinchBlueprint = GetFlinchBlueprint();
TSubclassOf<UAblAbility> Flinch = Cast<UAblAbility>(FlinchBlueprint)->GetBlueprintClass();

or


UBlueprint* FlinchBlueprint = GetFlinchBlueprint();
TSubclassOf<UAblAbility> Flinch = Cast<UAblAbility>(FlinchBlueprint)->GeneratedClass;

However, in all of these cases the result of Flinch is:


Class'Script/AbleCore.AblAbilityBlueprint'

Is it possible to have Flinch be the same as the BlueprintGeneratedClass like above?

Able v2.24 has been submitted.

Hi , revisiting Able after half a year of learning more UE4 Blueprinting. Finally understand the beauty of Gameplay Abilities! Is your dedicated server Example up to date?

It needs to be converted to the latest, but it should still work.Let me know otherwise and I’ll do the conversion myself and update it.

Goal: Whenever an actor takes damage, evaluate the type of damage and react accordingly for that actor.

First thought is to use UE4’s TakeDamage’s event “OnTakeAnyDamage” as a launching point for logic to respond to damage types for differing responses and logging. I would like to pass in a custom DamageType to have the different actors make decisions as this is a parameter of the TakeDamage actor method I am overriding and is included in the event being raised. Sadly, I see DamageTypes have to be a class and cannot be an instance.

Alternatives:

1 - add my own events in the blueprintlibrary call where damage is being calculated and pass the gameplay tag.

2 - I see you set gameplay tag task could work, but it does not fire off any event that I could respond to.

3 - Hmmm…maybe use the custom event task and have to remember to set it after every set gameplay tag is set?

I think I am going to try for the (1) alternative. Make a delegate off my class that inherits from actor and have the bluprintlibrary broadcast it.

Yea, I’m really not a fan of how the Damage type is setup by default in the engine (they’re classes as you point out which is pretty heavy weight just for what amounts to a simple flag / integer).

I basically handle this in the Burning Man example ( https://www.youtube.com/watch?v=-cAP5eqTb2Y ) by explicitly passing the Gameplay Tags during CalculateDamageForActor, so when the Actor actually receives the OnTakeAnyDamage callback - they can then look at the incoming tags for that damage.

While not 100% ideal, since those calls happen back to back, you don’t have to worry about some other damage call coming along and stomping your incoming tags (and if you are that worried, you could always store them as a queue).

Thanks. I watched the video again and picked up a bit more. I think that was the last video I watched when I was deciding on buying the plugin and was a bit glass eyed at that point.

I shied away from changing state in the calc dmg for actor method due to your warning about making it thread safe.

In your example you are setting Damage by Ability on the actor and I think I heard something to the effect if that is the only ability(?) that sets that variable then it should be safe? So if I have another ability, I would need to have a second (and so on) variable on the actor for the second ability to be setting in order to maybe(?) take advantage of async?

I am not really interested in trying async at the stage I am at, however I may want to not have abilities reuse the same ability variable on the actor for sanity sake. If having separate variables on that actor lends itself to using async in the future it would be good to start it now.

Yea, if you’re doing async you’d have to worry about two abilities possible running at the same time trying to set the same variable, in which case one would likely just stomp the other - not ideal, but it wouldn’t crash. Or you just use a queue, which is thread safe, and simply queue / dequeue the entries rather than directly setting a single variable.

It looks like Queue isn’t exposed to blueprints by default, but there’s a good step-by-step tutorial on adding that here: How to add C++ containers to our blueprints – Parallelcube

Regarding your burning man example, the BurnPassive ability sets gameplay tag “Status.Burning” which is done to the gameplaytag container on the ability component(?).

On the targetmannequiun, off the “Event AnyDamage” event, in the Check Burning method, the CharacterTags variable is checked for the above gameplay tag.

I don’t see where CharacterTags gets the “Status.Burning” tag.

I am assuming the abilitycomponent’s gameplay tag variable should be used to look for the Status.Burning? (GetGameplayTagContainer)

Correct, you want to keep all your tags in one place - so Ability Component makes sense since it already has support for them. The CharacterTags variable is just a temporary to copy the incoming damage’s tags to before evaluating damage. It’s then checked against the Character’s tags (e.g. the Ability Component) and if anything special needs to happen - it does it there.

You can also download the example and see how things work in more details.

Yep, did that. When I look for all the references for the CharacterTag variable, it only shows Gets and no sets in the blueprint. Only reason I am bringing it up is to see where I am missing something where it gets set. I see the IncommingTag off the DamageByAbility class variable and I see where the comparison is done in the CheckBurning method.

One thing to note is I opened up the example in 4.19.2 and I am seeing some weirdness in BurnPassive where all the custom events end in “_1”. So maybe something is getting lost in the conversion.

Ahh, right. The underlying methods changed names in 2.20 so that’s why you see the _1. Yea, I’ll need to remake those to get rid of that (Fun…). The get is either in the Ability Blueprint or the Character blueprint. Has to be set somewhere. :slight_smile:

The principle flow is still the same: When Damage is about to occur, pass in the tags for the incoming Ability. When damage does occur, check the Ability tags against the player tags, and do whatever combinations you want.

Is there a way I can send a reference to character class in Ability Context to minimize casting?

Not currently. To allow Able to be as flexible as possible, it only stores Actors. On the bright side, UE4’s casting system isn’t the normal C++ RTTI so the casts are very quick.