User Tag List

Page 2 of 2 FirstFirst 12
Results 41 to 76 of 76

Thread: GameplayAbilities and you.

  1. #41
    0
    Hi,
    Also from me a big thanks for the great description..

    I tried to implement a really simple Mana-Regeneration system, just for the sake of testing things out.
    -Create a AttributeSet with "Mana" , "MaxMana" and "ManaRegeneration"
    -Create a effect which periodically adds "ManaRegeneration" to Mana
    -added the Effect on the "Begin Play" event of the actor

    Works like it should right now, but now comes my question.
    When i try to clamp my mana to "MaxMana" in the "PreAttributeBaseChange" method it doesnt do anything at all
    Code:
    void UMagicAttributeSet::PreAttributeBaseChange(const FGameplayAttribute& Attribute, float& NewValue) const
    {
    	if (Attribute.GetUProperty() == FindFieldChecked<UProperty>(UMagicAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(UMagicAttributeSet, Mana)))
    	{
    		NewValue = FMath::Clamp(NewValue, 0.f, MaxMana);
    	}
    }
    as soon as i do exactly the same in the PreAttributeChange it works like a charm.
    Is there any reason why it does nothing in the "PreAttributeBaseChange"?

  2. #42
    0
    Quote Originally Posted by spongebrot View Post
    When i try to clamp my mana to "MaxMana" in the "PreAttributeBaseChange" method it doesnt do anything at all
    Code:
    void UMagicAttributeSet::PreAttributeBaseChange(const FGameplayAttribute& Attribute, float& NewValue) const
    {
    	if (Attribute.GetUProperty() == FindFieldChecked<UProperty>(UMagicAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(UMagicAttributeSet, Mana)))
    	{
    		NewValue = FMath::Clamp(NewValue, 0.f, MaxMana);
    	}
    }
    as soon as i do exactly the same in the PreAttributeChange it works like a charm.
    Is there any reason why it does nothing in the "PreAttributeBaseChange"?
    PreAttributeBaseChange is only triggered when you set the value via FActiveGameplayEffectsContainer::SetAttributeBaseValue. The most common way to invoke this is by going through UAbilitySystemComponent::SetNumericAttributeBase. If you access the attribute set directly, e.g., by using FGameplayAttribute::SetNumericValueChecked, only PreAttributeChange is called, not PreAttributeBaseChange.

    I've written a small test program to illustrate this. The ManaAttributeSet has four Mana_XXX variables that are either not clamped, clamped by one of the functions (between 0 and 2 for PreAttributeBaseChange and between -1 and 1 for PreAttributeChange) or clamped by both of them. There are two code paths: one that goes through a custom execution and sets the values like this:

    Code:
    	float OldNone{ ASC->GetNumericAttributeBase(FGameplayAttribute(None_Prop)) };
    	float OldBaseChangeOnly{ ASC->GetNumericAttributeChecked(FGameplayAttribute(BaseChangeOnly_Prop)) };
    	float OldChangeOnly{ ASC->GetNumericAttributeChecked(FGameplayAttribute(ChangeOnly_Prop)) };
    	float OldBoth{ ASC->GetNumericAttributeChecked(FGameplayAttribute(Both_Prop)) };
    	// UE_LOG(LogTemp, Warning, TEXT("RestoreMana: Old values: %.2f %.2f %.2f %.2f"), OldNone, OldBaseChangeOnly, OldChangeOnly, OldBoth);
    
    	ASC->SetNumericAttributeBase(FGameplayAttribute(None_Prop), OldNone + Delta);
    	ASC->SetNumericAttributeBase(FGameplayAttribute(BaseChangeOnly_Prop), OldBaseChangeOnly + Delta);
    	ASC->SetNumericAttributeBase(FGameplayAttribute(ChangeOnly_Prop), OldChangeOnly + Delta);
    	ASC->SetNumericAttributeBase(FGameplayAttribute(Both_Prop), OldBoth + Delta);
    
    	float NewNone{ ASC->GetNumericAttributeBase(FGameplayAttribute(None_Prop)) };
    	float NewBaseChangeOnly{ ASC->GetNumericAttributeChecked(FGameplayAttribute(BaseChangeOnly_Prop)) };
    	float NewChangeOnly{ ASC->GetNumericAttributeChecked(FGameplayAttribute(ChangeOnly_Prop)) };
    	float NewBoth{ ASC->GetNumericAttributeChecked(FGameplayAttribute(Both_Prop)) };
    
    	UE_LOG(LogTemp, Warning, TEXT("RestoreMana: New values: %.2f %.2f %.2f %.2f"), NewNone, NewBaseChangeOnly, NewChangeOnly, NewBoth);
    in this case the output is as expected:
    Code:
    LogTemp:Warning: RestoreMana: New values: 0.40 0.40 0.40 0.40
    LogTemp:Warning: RestoreMana: New values: 0.80 0.80 0.80 0.80
    LogTemp:Warning: RestoreMana: New values: 1.20 1.20 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 1.60 1.60 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.00 2.00 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.40 2.00 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.80 2.00 1.00 1.00
    The second code path looks like this:
    Code:
    	float OldNone{ ManaAttributeSet->Mana_None.GetCurrentValue() };
    	float OldBaseChangeOnly{ ManaAttributeSet->Mana_BaseChangeOnly.GetCurrentValue() };
    	float OldChangeOnly{ ManaAttributeSet->Mana_ChangeOnly.GetCurrentValue() };
    	float OldBoth{ ManaAttributeSet->Mana_Both.GetCurrentValue() };
    
    	float NewNone{ OldNone + Delta };
    	None_Attr.SetNumericValueChecked(NewNone, ManaAttributeSet);
    	float NewBaseChangeOnly{ OldBaseChangeOnly + Delta };
    	BaseChangeOnly_Attr.SetNumericValueChecked(NewBaseChangeOnly, ManaAttributeSet);
    	float NewChangeOnly{ OldChangeOnly + Delta };
    	ChangeOnly_Attr.SetNumericValueChecked(NewChangeOnly, ManaAttributeSet);
    	float NewBoth{ OldBoth + Delta };
    	Both_Attr.SetNumericValueChecked(NewBoth, ManaAttributeSet);
    
    
    	UE_LOG(LogTemp, Warning, TEXT("RestoreMana: New values: %.2f %.2f %.2f %.2f"), NewNone, NewBaseChangeOnly, NewChangeOnly, NewBoth);
    and in that case the output mirrors the behavior you see:

    Code:
    LogTemp:Warning: RestoreMana: New values: 0.40 0.40 0.40 0.40
    LogTemp:Warning: RestoreMana: New values: 0.80 0.80 0.80 0.80
    LogTemp:Warning: RestoreMana: New values: 1.20 1.20 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 1.60 1.60 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.00 2.00 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.40 2.40 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 2.80 2.80 1.00 1.00
    LogTemp:Warning: RestoreMana: New values: 3.20 3.20 1.00 1.00
    Only PreAttributeChange clamps the value, PreAttributeBaseChange is not invoked.

    Of course the abilities system is complicated enough that you might have come across a totally different effect, but that seemed the most likely explanation to me without any further information

    P.S. A big "thank you" to Kaz for the original post from me as well. The abilities system is great for so many things, but a beast to figure out from the source code. Hopefully more people will be able to benefit now that there is documentation available.
    Last edited by Matthias Hölzl; 03-10-2017 at 01:44 AM.

  3. #43
    0
    Infiltrator
    Join Date
    Jun 2015
    Posts
    20
    Quote Originally Posted by Raph13QC View Post
    Hey!
    First, thank you so much for this post : amazing job!!
    I'm having issue with Tag handling.

    In a gameplay ability, I understand that if I say "ok, the one triggering this must posses a specific tag,if not, I'll just don't do it"
    The problem that I'm facing is "How to I set a gameplay tag" on, per say, the BP_Hero in the example from Dave.

    To be working, must it implement the interface UGameplayTagAssetInterface ?
    I've tried, in BP, the "Add Asset Tag" and "Add Granted Tag" but not working.
    In dispair, I also tried to add a random GameplayTag variable but of course it didn't work.

    Can you help please?
    I can't tell you if this is the right way or not, but you could add the tag to an effect and then apply the effect to the actor.

  4. #44
    0
    is there a way to globally trigger an ability without the ability having to be given to an actor first?

  5. #45
    0
    Quote Originally Posted by falola View Post
    is there a way to globally trigger an ability without the ability having to be given to an actor first?
    Well, yes and no

    By default abilities themselves are not instanced, and so they don't belong to an actor. (They can optionally be instanced by execution or by actor in which case they do have an owner.) However, to actually do something with the ability you need to provide an actor and an ability system component.

    Well, actually you need to provide two actors: UGameplayAbility::CanActivateAbility, UGameplayAbility::ActivateAbility, etc. all take an FGameplayAbilityActorInfo as argument. This struct contains attributes for two actors: an Owner and an Avatar. According to the documentation the Owner should not be null whereas the Avatar may be. However, CanActivateAbility checks whether the Avatar is null and returns false if it is. So you cannot really use an ability without providing both Owner and Avatar. These are, e.g., used as instigator and causer, respectively, if your ability creates gameplay effects and the avatar is used as the source for target locations. But I don't think anything prevents you from using the same actor for both roles.

    To activate the ability you want to call UGameplayAbility::ActivateAbility after doing some setup work. Problem is, this method is protected, and there exists no obvious caller in UGameplayAbility. The comments in GameplayAbility.h mention a TryActivateAbility method that achieves this, but this method does not (perhaps no longer?) exist in UGameplayAbility, only in UAbilitySystemComponent. So it seems to me that you cannot actually activate the ability without going through an ability system component. (I might, of course, miss something.)

    In summary, I don't think you can trigger an ability without using some actor and ability system component. But nothing prevents you from having a single "global ability actor" in your world that triggers all abilities that you don't want to give to individual actors, if that suits your design.
    Last edited by Matthias Hölzl; 03-11-2017 at 03:49 AM. Reason: Fix typo

  6. #46
    0
    Good idea with the global actor to use to trigger abilities. I do have another question. How do you remove an effect but keep the attribute change that it applied? My issue is that i have a poison gameplay effect that will only apply the modifier when i add Round.End to the actor using the OngoingTagRequirements in the gameplay effect. If the duration is set to instant then it doesn't apply so i have to set the duration to infinite. Everything works until i remove the gameplay effect. It reverts the attribute change adding the health back to the player. Any ideas?

    Also can you connect an actor's tag container to the ability system component's tag container (my actor derives off IGameplayTagAssetInterface)? It looks like the ability system has its own tag container so there is no point of having a tag container in the actor since adding tags to that container doesn't get added to the ability system's one. So should i even have a tag container in the actor or just work off the ability system component's one?
    Last edited by falola; 03-11-2017 at 10:15 PM.

  7. #47
    0
    Deary me, I wouldn't have thought that the thread would remain so active. I'll try to kinda, sorta answer some of the still open questions.

    Hey!
    First, thank you so much for this post : amazing job!!
    I'm having issue with Tag handling.

    In a gameplay ability, I understand that if I say "ok, the one triggering this must posses a specific tag,if not, I'll just don't do it"
    The problem that I'm facing is "How to I set a gameplay tag" on, per say, the BP_Hero in the example from Dave.

    To be working, must it implement the interface UGameplayTagAssetInterface ?
    I've tried, in BP, the "Add Asset Tag" and "Add Granted Tag" but not working.
    In dispair, I also tried to add a random GameplayTag variable but of course it didn't work.

    Can you help please?
    To my knowledge, the tags are attached to the ability system component, rather than the actor the ability system acts through. Which kinda makes sense if you think about it, really. Not like it makes a difference; there isn't really any convenient way to plainly add a tag, and just a tag, to an ability system that's exposed to blueprints.

    The standard way to add a granted tag to an ability system of choice is to apply a GameplayEffect that has the tag in question set to be applied to the affected actor(you can set extra tags to grant for each gameplay effect spec, so you can decide dynamically which ones the effect will apply as well, and don't need an extra GE for every individual tag application). I believe you can also add a granted tag without Gameplay Effect by using the C++ function AddLooseGameplayTag in the AbilitySystemComponent class, however the code comments specifically warn that tags added this way are not replicated automatically, and I am unsure how safe this method is as a whole. Unless you have a good reason not to, I'd think applying a permanent Gameplay Effect spec with your tag of choice added as extra granted tag should about do the trick.

    Good idea with the global actor to use to trigger abilities. I do have another question. How do you remove an effect but keep the attribute change that it applied? My issue is that i have a poison gameplay effect that will only apply the modifier when i add Round.End to the actor using the OngoingTagRequirements in the gameplay effect. If the duration is set to instant then it doesn't apply so i have to set the duration to infinite. Everything works until i remove the gameplay effect. It reverts the attribute change adding the health back to the player. Any ideas?
    Huh, that's a tricky question, depending on what you wish to do.

    I know instant effect replication uses something funky like that, it treats an instant GameplayEffect as infinite until the server can verify and confirm the application for real, rolling it back if this is not the case. I'm looking through it there, and it seems like you are able to define how a spec behaves by setting its duration in specific ways(infinite duration is defined as -1.0f, instant as 0.0f), and as you can copy the old GameplayEffectSpec due to being a struct with no real deep copy issues, you could probably remove and replace it with an instant variation of it when the time is right.

    That sounds like a bit of a weird hack though(I mean, experiments cost nuthin', just saying it may be a little tryhard), so I suppose the more reasonable answer might be to just set up an ability(either a newly created one for the job or the source ability) to listen for either the removal of the "preview" poison effect and apply a separate, permanent Gameplay Effect with similar modifiers, or to just wait for the Round.End tag to happen to your actor before abilities start unravelling their effects(which could easily be done with ability tasks).

    Up to you how you want to do it, really.

    Also can you connect an actor's tag container to the ability system component's tag container (my actor derives off IGameplayTagAssetInterface)? It looks like the ability system has its own tag container so there is no point of having a tag container in the actor since adding tags to that container doesn't get added to the ability system's one. So should i even have a tag container in the actor or just work off the ability system component's one?
    You probably could link the containers in some strange way, but there would be little point.

    The actor's tags doesn't and probably shouldn't really influence the ability system in any way. You can set up and use an actor tag container for other things if you wish, however. The beauty of gameplay tags as a whole is that they leave few restrictions, they give you a very basic, very general tool and let you do whatever with it.
    Last edited by KZJ; 03-11-2017 at 10:53 PM.

  8. #48
    0
    Any chance you can do a small tutorial about Ability Tasks and how to set them up / use them?

  9. #49
    0
    Not much to talk about how to use them. They're blueprint nodes you can call in Ability graphs that wait for an outside stimuli before continuing, usually possessing an unlabelled top exec route that you may use to continue calling functions within the current frame and labelled exec pins that will run its attached route of functions at a later time, much like how delays work but with thigns other than time, usually. They usually do what they advertise in their name/description, they support multiplayer and will do their best predicting and correcting themselves. They will only run for as long as the ability is active, so the End Ability node will prematurely end all pending ability tasks originating from that ability, as well(so you probably want to place things that HAVE to happen, no matter how the ability ended, in the EndAbility function or whatever it was called. One example I could think off probably being purging off a buff that roots you in place as you play your casting animation).

    I would think they are rather self-explanatory.

    That being said, if your question is about making your own ability tasks and setting up/using them, then I would have no idea how to do that, sorry. Not really feeling having to dissect their source code myself, either, especially considering Gameplay Tasks as a whole are probably a module big enough to cover a small tutorial on their own anyway(especially since their use is not actually limited to the ability system alone). Latent actions in UE4 C++ and, by extension, Gameplay/Ability Tasks are honestly a bunch of crud to understand and set up(I mean, maybe I just suck. That's always a possibility), so I'm pretty happy about not having to deal with the act of setting them up currently.

    Maybe I'll go through it and write something down some day, but currently I am not really planning on it. The ability tasks built into the system already do about most generic things you could ask for, anyhow.

  10. #50
    0
    Does this work with Combos and timed press system?
    Or do we have to code them again?

    Also, can unreal use notepad++ to deal with code?
    Visual studio is just way too heavy.

  11. #51

  12. #52
    0
    I've created a wiki page using the text of the OP as it stands right now. I pretty much just copied and pasted directly, fixing the formatting to match the wiki formatting as I went. Feel free to make any modifications to the page if needed.

  13. #53
    0
    Thanks to @KZJ for the proper guide and @Jay2645 for the wiki! Gameplay Abilities/Tags are just awesome and the system is so robust that the possibilities are endless!

    Here is a quick preview. Testing as client with dedicated server.


  14. #54
    0
    Hey everyone,
    First, thanks for your answers, more and more I feel like the gameplay effect is the go-to-bridge for anything related to the ability system.

    One thing I'd like to know is about the AttributeSet. These are CPP only for as far as I can tell (inheriting them in blueprint only allows you to modify the default values -if they are marked as editable in cpp-).
    Can somebody tell me why and if there's any workaround for it?

    I also found that I could link a datatable to these attributes via the initstat to set stuff very easily but it only allows me to modify values, not creating new fields.

    Cheers and thanks again so much!

  15. #55
    0
    Quote Originally Posted by Raph13QC View Post
    One thing I'd like to know is about the AttributeSet. These are CPP only for as far as I can tell (inheriting them in blueprint only allows you to modify the default values -if they are marked as editable in cpp-).
    Can somebody tell me why and if there's any workaround for it?
    It kind of sucks to properly expose AttributeSet creation to blueprints, because you need to set up lifetime replication in unique ways, require a repnotify function with macro inside for each attribute to guarantee that replication works properly, and the Attribute change functions pretty much require you to identify the attribute that's currently being changed by checking up the UProperty belonging to them.

    I am not convinced that it is impossible or even all that difficult to properly expose the creation of new attribute sets with new attributes within blueprints period, but I would think that it's barely worth to do it considering it seems like such an annoying extra mile to take when the cpp code is so incredibly trivial(if obnoxiously wordy per attribute) to write, once you are aware of which macros to use where. It's not like you will keep adding new attributes to your project all the time either, it's the kind of thing you're usually done planning and implementing relatively early into the project, with some minor tweaks and additions happening afterwards.

  16. #56
    0
    Thanks for this! Timing is perfect as I was kind of stuck of how I would handle my abilities and perk system! I hope I can wrap my artist head around all this haha!
    I'm still confused by the keybinding actions as Im making a tactical turned based rpg. What I do now is let the playercontroller handle all input and call event dispatchers to my unitmanager which then checks which unit is active and then running the Try Activate Ability By Class function.. Not sure if my implementation will work in the long run but the whole system looks promising! Thanks again for the write up!

  17. #57
    0
    So there is one thing I am not quite sure about these - do abilities start montages or do montages start abilities? I'm sure there's an argument to be made for both (and use-cases for both) but for the general case it seems to be the former. Which makes it all the more confusing that GameplayAbilities don't have "MontageToPlay" or some such already in them, as it sounds like it's a fairly common thing to do.
    Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  18. #58
    0
    Quote Originally Posted by DamirH View Post
    So there is one thing I am not quite sure about these - do abilities start montages or do montages start abilities? I'm sure there's an argument to be made for both (and use-cases for both) but for the general case it seems to be the former. Which makes it all the more confusing that GameplayAbilities don't have "MontageToPlay" or some such already in them, as it sounds like it's a fairly common thing to do.
    Not sure if I understand the question, or even the problem.

    Abilities can start montages by using the ability task fittingly called PlayMontageAndWait, and this is usually what you're expected to use when dealing with montages in the context of an ability, such as for example a cast animation that plays prior to firing a projectile. Due to being an ability task, it has multiple outputs that help in tying functionality to the montage(4, namely On Completed, On Blend Out, On Interrupted and On Cancelled). The only annoying thing about doing it that way is that you can't really set up an animation that triggers the rest of the ability's effect halfway through without playing around with a separate delay task, but that can be solved by splitting the casting montage of choice into a pre-effect and a post-effect montage.

    Tying abilities to a cast animation, so the other way around, is usually a suboptimal idea, because abilities should be designed to be as self-contained as you can make them. Having the montage and, by extension, its length be defined outside of the ability seems counterproductive to this goal. Moreover, due to the fact that abilities have access to tasks and can pretty much end themselves whenever they want, there is no real benefit from doing it the other way around than intended.

    That being said, I would think that a cosmetic/purely visual animation as a result of a gameplay effect, such as a "flailing and panicking because on fire" animation or some such thing could probably be handled as part of a gameplay cue. Not sure actually. It would make sense to me because these are the kinds of things gameplay cues are used in general and ability systems can only play one montage this way at a time(for fairly obvious reasons), but I don't know if there's any important interactions to watch out for(you would probably have to check if you aren't overwriting a montage a montage ability task before playing such an animation, though. The ability system keeps track of the montage that's currently playing as a product of a task, but I don't know the name of the getter function or if it's evenr eadily available).

    But yeah, if your animation isn't 100% cosmetic, use the ability task. You could even make a child ability class for generic "Play Montage X and, when successful, follow through with effects defined in function Y" kinda abilities.

  19. #59
    0
    Hmm, I missed the PlayMontageAndWait function. I was mostly concerned on what t he intent is of the system, and the ability -> montage workflow seems to be the correct answer.
    Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  20. #60
    0
    The long story short, is that you should use animations only in cosmetic manner. You should not use them to actually trigger parts of abilities, it's opposite to what what ability system is trying to do.

    I can see point on why you would want to trigger something from montage, like shooting fireball from hand ( if you want it to be perfectly synced), but in that way you limit yourself to perfectly timed animation (which will determine cast time of ability), which isn't good approach in something like RPG (IMO).

    Setting it up to use animation only as presentation layer is probably more complex and I honestly haven't found good workflow for it yet, but it still going to be more beneficial (at least for me) in long term.

    It would nice to actually know how it is handled for casters in Paragon (like Gideon).
    https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

  21. #61
    0
    Quote Originally Posted by iniside View Post
    The long story short, is that you should use animations only in cosmetic manner. You should not use them to actually trigger parts of abilities, it's opposite to what what ability system is trying to do.

    I can see point on why you would want to trigger something from montage, like shooting fireball from hand ( if you want it to be perfectly synced), but in that way you limit yourself to perfectly timed animation (which will determine cast time of ability), which isn't good approach in something like RPG (IMO).

    Setting it up to use animation only as presentation layer is probably more complex and I honestly haven't found good workflow for it yet, but it still going to be more beneficial (at least for me) in long term.

    It would nice to actually know how it is handled for casters in Paragon (like Gideon).
    I would be curious too, actually. There's a compelling point to be made that tying a cast time/channel/whatever to a visual animation is probably very stupid for the simple reason that tying functionality to visuals and not the toher way around tends to be a no-no, but on the other hand you could just make it so that the montage playback rate is adjusted so that the montage duration adjusts itself to a concretely defined duration variable in the ability(basically make the play rate of the montage (normal montage duration / Cast time value) ), and not the other way around. Then you'd ultimately be left with just a delay node that ensures that the animation tied to the ability must be played until the end, which can be crucial for games where visual tells are key.

    It would also seem strange to me that you'd have to split a montage for a before-effect and after-effect section of an animation. Would you do a delay task that would perhaps be ended prematurely if the animation itself is cancelled/interrupted, would you actually have to split and play 2 montage tasks, would you create a new ability task class that is set up to listen for, say, an animation notify within the montage passed as parameter, or what?

    I wonder if it would be too much to ask for an example ability implementation from a random active Paragon ability of choice. Prob'ly, but it could answer some questions about what the best practices for each thing are.
    Last edited by KZJ; 03-21-2017 at 12:10 PM.

  22. #62
    0
    Well honestly I do not see the benefit of that philosophy. I use animations to sync stuff up without needing to enter arbitrary magic numbers for ranges.

    As an example - I use a modified version of the state machine plugin that was developed on the fighting game training livestream. They entered ranges for cancel windows which was a big no for me as our animations are often being tweaked, sped up, slowed down etc. by the gameplay designers. What I ended up doing is create an anim notify that simply allows the curent move to cancel. As such I define my cancel windows via notifies. This is especially important since we have named cancel windows (cancel for next melee swing, cancel for special attack etc.)

    The cast time argument isn't really valid because for those situations you usually have CastStart, CastLoop and CastExecute. You simply stick to the loop as long as your cast time is.

    In an ideal world animations would only be the presentation layer but the way I see it this is an example of rigid design philosophy actually standing in the way of the design.
    Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  23. #63
    0
    I don't think either answer is truly right in all situations, because games with an almost fighting game-esque focus on animations and visual cues pretty much require an animation and the frame- and hitbox-data of that animation to be very closely intertwined, because in a way the animation is pretty much the attack in such a case. At the same time, MOBAs such as Dota are primarily number games, and the timing of the effect itself is what's important, not the animation of the comparably tiny character that mostly only aids in making what skills are used easier to follow. As such, changing the animation itself should have no business changing the actual casting time.

  24. #64
    0
    Quote Originally Posted by KZJ View Post
    I don't think either answer is truly right in all situations, because games with an almost fighting game-esque focus on animations and visual cues pretty much require an animation and the frame- and hitbox-data of that animation to be very closely intertwined, because in a way the animation is pretty much the attack in such a case. At the same time, MOBAs such as Dota are primarily number games, and the timing of the effect itself is what's important, not the animation of the comparably tiny character that mostly only aids in making what skills are used easier to follow. As such, changing the animation itself should have no business changing the actual casting time.
    Yes but that is a moot point. Any spell with a cast time will have a 3 phase montage - start, loop and end.You will simply keep the montage in the loop state until the cast time is done.
    Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  25. #65
    0
    Samaritan
    Join Date
    Mar 2014
    Posts
    82
    Hi, I want to add another thanks to KSJ for creating this.

    I've been playing with and making small modifications to the sample project and feeling pretty good about things. One thing I'm unsure of is the proper way to display information to the user (via widget for example)

    Things I would like to show but haven't figured out how:

    - a list of all effects currently active on the player (e.g. buff/debuff icons)
    - time remaining of temporary effects
    - time remaining for ability cooldown effects

    Things I did figure out how:

    - Health or any other attribute (by using the get attribute node shown below)


  26. #66
    0
    Infiltrator
    Join Date
    Jun 2015
    Posts
    20
    Quote Originally Posted by tmek View Post
    Hi, I want to add another thanks to KSJ for creating this.

    I've been playing with and making small modifications to the sample project and feeling pretty good about things. One thing I'm unsure of is the proper way to display information to the user (via widget for example)

    Things I would like to show but haven't figured out how:

    - a list of all effects currently active on the player (e.g. buff/debuff icons)
    - time remaining of temporary effects
    - time remaining for ability cooldown effects

    Things I did figure out how:

    - Health or any other attribute (by using the get attribute node shown below)

    For a list of all current effects you can query the tags on that player. If you're finding you need to do this a lot then I think you should step back for a minute and think about whether you can do it in a more modular way. I have a lot of status effects in a fairly standard dungeon crawler and the only time I iterate over all the tags/effects is when I'm debugging.

    For time remaining of effects you can use one of several methods like:


    TArray<float> GetActiveEffectsTimeRemaining(const FGameplayEffectQuery& Query) const;


    but this method isn't exposed to blueprint and for HUD icons of status effects (like slow or burning or whatever) you might be want to put it in the cue.

    since cooldowns are effects, you can use the same system to get time remaining for cooldowns. There is a convenience method

    UFUNCTION(BlueprintCallable, Category = Ability)
    float GetCooldownTimeRemaining() const;

  27. #67
    0
    Hey guys, just a quick heads up - I started my own analysis on this system and so far I've written a comprehensive analysis on Ability Sets. You can take a look here.
    Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

  28. #68
    0
    Hello,

    thanks for this very useful post.

    I have started to investigate the system a bit, and I'm now in the process of converting some of the abilities I coded by hand in C++ to this system.

    I have a pretty good understanding of the various elements of the system, but I don't get why I have this issue with my attempt to implement a Sprint ability.

    So far, I have this game play ability:
    Name:  2017-05-09 23_09_59-RWC [DebugGame] - Unreal Editor.png
Views: 194
Size:  144.5 KB

    As you can see, once my ability starts, I apply a GameplayEffect GE_Sprint_Stamina and wait to end the ability for the player to release the sprint button, or when he runs out of stamina.

    Once the ability ends, I remove all game play effects which granted the Abilities.Movement.Sprint tag to the owner.

    Here is my gameplay effect:
    Name:  2017-05-09 23_14_05-RWC [DebugGame] - Unreal Editor.png
Views: 196
Size:  50.8 KB

    It is pretty simple I think : I just periodically decrease the stamina, and I grant the Abilities.Movement.Sprint.

    This works well. When I press the sprint button, the stamina starts to decrease, until I release the button.

    So far, so good.

    But...

    In the tick event of the blueprint of the character, I iterate over all the tags, to check the tag has been correctly removed:
    Name:  2017-05-09 23_17_06-RWC [DebugGame] - Unreal Editor.png
Views: 194
Size:  119.7 KB

    Once I start sprinting, I can see the tag is in the list. But when I release the button, the tag is still displayed each tick.

    Is there a better solution to this?

    Thanks and keep the good work !
    My game dev blog : http://www.emidee.net/

  29. #69
    0
    After digging in the source code, I confirm the tags are correctly removed from the ability system component when the ability ends.

    The problem lies in the output of the owned tags I display each tick.

    I also tried with the built-in GetDebugStringFromGameplayTagContainer, but with the same outcome.

    Name:  2017-05-10 11_19_38-RWC [DebugGame] - Unreal Editor.png
Views: 183
Size:  66.8 KB
    My game dev blog : http://www.emidee.net/

  30. #70
    0
    Hello,

    I have another question: how would you go to undo a modifier when a game play effect ends?

    I have 2 attributes : WalkSpeed and WalkSpeedMultiplier. I also have a Sprint ability. When this ability is active, I would like to set multiply the WalkspeedModifier by 2.0f for example. And when the sprint ability is ended, I would like to divide this WalkSpeedMultiplier by 2.0f.

    Thinking about this, my assumption is that it is only possible using 2 gameplay effects.

    Am I correct?
    My game dev blog : http://www.emidee.net/

  31. #71
    0
    Maybe I misunderstand the question, but don't you just need to have one permanent gameplay effect for this? Modifiers come and go with the GameplayEffect they're attached to, unless their Gameplay Effect is instant, in which case they become permanent.

  32. #72
    0
    No you got the question right.

    I got confused because of this weird issue I was talking about before. The debug output of all the game play tags was displaying all the tags the owner ever had, including those who were not supposed to be active.

    Your answer is correct too. I had to set the duration of the effects to Infinite to undo the buff when the gameplay effect is remoed
    My game dev blog : http://www.emidee.net/

  33. #73
    0
    Hi guys, I'm wasting days trying to understand this Gameplay Abilities system but some things are still unclear to me.
    My problem is not using C++, I use it regularly, my problem is how to design spells using this system, there are only simple examples on the Web.

    Let's say I want to make a spell like this one:

    1.Casts for 1 second
    2.Every 3 seconds heals the player
    3.When the duration ends it enables another spell

    To heal periodically I can simply use a GameplayEffect with a period of X seconds, my real problem is that I can't find a way to activate an ability when a GameplayEffect ends (there is only OwnedTagAdded but not OwnedTagRemoved) and how to create a Casting time.

    How would you create the spell mentioned above using the Gameplay Abilities?

  34. #74
    0
    To activate an ability from a gameplay effect, I think you can use the triggers of that ability, which can watch whenever a tag is added to the owner.

    For the 1 second cast time, in your ability, I would add a WaitDelay task of 1 second right after your ability starts, from which you would plug your gameplay code. I would also add a WaitInputRelease task to cancel if the player released the button before that 1 second delay for example, if you need.

    I think that would be a good starting point (I don't have a lot of experience with the system right now)
    My game dev blog : http://www.emidee.net/

  35. #75
    0
    Quote Originally Posted by woppin View Post
    For a list of all current effects you can query the tags on that player. If you're finding you need to do this a lot then I think you should step back for a minute and think about whether you can do it in a more modular way. I have a lot of status effects in a fairly standard dungeon crawler and the only time I iterate over all the tags/effects is when I'm debugging.

    For time remaining of effects you can use one of several methods like:


    TArray<float> GetActiveEffectsTimeRemaining(const FGameplayEffectQuery& Query) const;


    but this method isn't exposed to blueprint and for HUD icons of status effects (like slow or burning or whatever) you might be want to put it in the cue.

    since cooldowns are effects, you can use the same system to get time remaining for cooldowns. There is a convenience method

    UFUNCTION(BlueprintCallable, Category = Ability)
    float GetCooldownTimeRemaining() const;
    Could you expand a bit on this? How would you go about making a HUD with cooldowns? Or tie things to the HUD in general. Is it possible with blueprints?
    Last edited by Eicosanol; 05-24-2017 at 10:37 AM.

  36. #76
    0
    Infiltrator
    Join Date
    Jun 2015
    Posts
    20
    Quote Originally Posted by Eicosanol View Post
    Could you expand a bit on this? How would you go about making a HUD with cooldowns? Or tie things to the HUD in general. Is it possible with blueprints?
    If you're asking for pure blueprint solutions then GameplayAbilities is unlikely to fit the bill. You can query the cooldown time remaining based on which cooldown effect you've assigned to an ability, how you tie that to your HUD is entirely up to you. You could put a translucent tint progressbar on top of each ability icon and bind its %age based on the cooldown time for something quite cheap, or display a rounded integer, or whatever. I don't use cooldowns at the moment since my abilities are all mana cost, so I don't have an example to show sorry.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •