{"id":3139,"date":"2021-01-02T14:10:10","date_gmt":"2021-01-02T06:10:10","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=3139"},"modified":"2021-01-02T19:42:18","modified_gmt":"2021-01-02T11:42:18","slug":"gameplayabilities-api-implementing-buffs-with-gameplayeffect","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=3139","title":{"rendered":"GameplayAbilities API \u2013 implementing buffs with GameplayEffect"},"content":{"rendered":"\n<p> A buff is just an effect that introduces a temporary, permanent, or recurring change to a game unit&#8217;s attributes from its\u00a0AttributeSet. Buffs can either be good or bad, supplying either bonuses or penalties. For example, you might have a hex buff that slows a unit to half speed, an angel wing buff that increases unit speed by 2x, or a cherub buff that recovers\u00a05 hp\u00a0every 5 seconds for 3 minutes. A\u00a0GameplayEffect\u00a0affects an individual gameplay attribute in the\u00a0UAttributeSet\u00a0that&#8217;s attached to an\u00a0AbilitySystemComponent\u00a0of an Actor. <\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Brainstorm your game units&#8217; effects that happen during the game. Be sure that you&#8217;ve created an&nbsp;AttributeSet, as shown in the previous recipe, with gameplay attributes that you&#8217;d like to affect. Select an effect to implement and follow the succeeding steps with your example.You may want to turn&nbsp;LogAbilitySystem&nbsp;into a&nbsp;VeryVerbose&nbsp;setting by going to the&nbsp;Output Log&nbsp;and typing&nbsp;`, and then&nbsp;Log LogAbilitySystem All. This will display much more information from&nbsp;AbilitySystem&nbsp;in the&nbsp;Output Log, making it easier to see what&#8217;s going on within the system.\n\n<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<p>In the following steps, we&#8217;ll construct a quick&nbsp;GameplayEffect&nbsp;that heals&nbsp;50 hp&nbsp;to the selected unit&#8217;s&nbsp;AttributeSet:<\/p>\n\n\n\n<ol><li>Open up the&nbsp;Warrior.h&nbsp;file we created previously. In there, add the following function definition:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">void TestGameplayEffect();<\/pre>\n\n\n\n<ol><li>Afterwards, open up&nbsp;Warrior.cpp&nbsp;and add the following methods:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">inline UGameplayEffect* ConstructGameplayEffect(FString name)<br>{<br>    return NewObject&lt;UGameplayEffect&gt;(GetTransientPackage(), FName(*name));<br>}<br><br>inline FGameplayModifierInfo&amp; AddModifier(<br>    UGameplayEffect* Effect, UProperty* Property,<br>    EGameplayModOp::Type Op,<br>    const FGameplayEffectModifierMagnitude&amp; Magnitude)<br>{<br>    int32 index = Effect-&gt;Modifiers.Num();<br>    Effect-&gt;Modifiers.SetNum(index + 1);<br>    FGameplayModifierInfo&amp; Info = Effect-&gt;Modifiers[index];<br>    Info.ModifierMagnitude = Magnitude;<br>    Info.ModifierOp = Op;<br>    Info.Attribute.SetUProperty(Property);<br>    return Info;<br>}<\/pre>\n\n\n\n<ol><li>Then, add the following code to implement:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">void AWarrior::TestGameplayEffect()<br>{<br>    \/\/ Construct &amp; retrieve UProperty to affect<br>    UGameplayEffect* RecoverHP = ConstructGameplayEffect(\"RecoverHP\");<br><br>    \/\/ Compile-time checked retrieval of Hp UPROPERTY()<br>    \/\/ from our UGameUnitAttributeSet class (listed in<br>    \/\/ UGameUnitAttributeSet.h)<br>    UProperty* hpProperty = FindFieldChecked&lt;UProperty&gt;(<br>        UGameUnitAttributeSet::StaticClass(),<br>        GET_MEMBER_NAME_CHECKED(UGameUnitAttributeSet, Hp));<br><br>}<\/pre>\n\n\n\n<ol><li>Use the&nbsp;AddModifier&nbsp;function to change the&nbsp;Hp&nbsp;field of&nbsp;GameUnitAttributeSet, as follows:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">  \/\/ Command the addition of +5 HP to the hpProperty<br>  AddModifier(RecoverHP, hpProperty, EGameplayModOp::Additive, FScalableFloat(50.f));<\/pre>\n\n\n\n<ol><li>Fill in the other properties of&nbsp;GameplayEffect, including fields such as&nbsp;DurationPolicy&nbsp;and&nbsp;ChanceToApplyToTarget, or any other fields that you&#8217;d like to modify, as follows:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ .. for a fixed-duration of 10 seconds ..<br>RecoverHP-&gt;DurationPolicy = EGameplayEffectDurationType::HasDuration;<br>RecoverHP-&gt;DurationMagnitude = FScalableFloat(10.f);<br><br>\/\/ .. with 100% chance of success ..<br>RecoverHP-&gt;ChanceToApplyToTarget = 1.f;<br><br>\/\/ .. with recurrency (Period) of 0.5 seconds<br>RecoverHP-&gt;Period = 0.5f;<\/pre>\n\n\n\n<ol><li>Apply the effect to an&nbsp;AbilitySystemComponent&nbsp;of your choice. The underlying&nbsp;UAttributeSet&nbsp;will be affected and modified by your call, as shown in the following piece of code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">FActiveGameplayEffectHandle recoverHpEffectHandle =<br>    AbilitySystemComponent-&gt;ApplyGameplayEffectToTarget(<br>        RecoverHP, AbilitySystemComponent, 1.f);<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>GameplayEffects&nbsp;are simply little objects that effect changes to an actor&#8217;s&nbsp;AttributeSet.&nbsp;GameplayEffects&nbsp;can occur once, or repeatedly, in intervals over a&nbsp;Period. You can program-in effects pretty quickly, and the&nbsp;GameplayEffect&nbsp;class creation is intended to be inline.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">There&#8217;s more&#8230;<\/h1>\n\n\n\n<p>Once the&nbsp;GameplayEffect&nbsp;is active, you will receive an&nbsp;FActiveGameplayEffectHandle. You can use this handle to attach a function delegate to run when the effect is over using the&nbsp;OnRemovedDelegate&nbsp;member of the&nbsp;FActiveGameplayEffectHandle. For example, you might call&nbsp;the following code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FOnActiveGameplayEffectRemoved* ep = AbilitySystemComponent-&gt;<br>    OnGameplayEffectRemovedDelegate(recoverHpEffectHandle);<br><br>if (ep) <br>{<br>    ep-&gt;AddLambda([]() <br>    {<br>        UE_LOG(LogTemp, Warning, TEXT(\"Recover effect has been removed.\"), 1);<br>    });<br>}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A buff is just an effect that introduces a temporary, p [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,1],"tags":[26],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3139"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3139"}],"version-history":[{"count":1,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3139\/revisions"}],"predecessor-version":[{"id":3143,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3139\/revisions\/3143"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}