{"id":3123,"date":"2021-01-02T14:08:08","date_gmt":"2021-01-02T06:08:08","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=3123"},"modified":"2021-01-02T19:42:26","modified_gmt":"2021-01-02T11:42:26","slug":"api-rotation-using-frotationmatrix-to-have-one-object-face-another","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=3123","title":{"rendered":"API \u2013 rotation using FRotationMatrix to have one object face another"},"content":{"rendered":"\n<p> FRotationMatrix\u00a0offers matrix construction using a series of\u00a0::Make*\u00a0routines. They are easy to use and useful to get one object to face another. Say you have two objects, one of which is following the other. We want the rotation of the follower to always be facing what it is following. The construction methods of\u00a0FRotationMatrix\u00a0make this easy to do. <\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Have two actors in a scene, one of which should face the other.\u00a0<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Add a new&nbsp;C++ Actor Component&nbsp;for the follower called&nbsp;FollowActorComponent&nbsp;(see the&nbsp;<em>Core\/Math API \u2013 rotation using FRotator<\/em>&nbsp;recipe if you need help with this).<\/li><li>From the&nbsp;FollowActorComponent.h&nbsp;file, we need to have a reference to the object we want to follow, so add the following:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )<br>class CHAPTER_11_API UFollowActorComponent : public UActorComponent<br>{<br>    GENERATED_BODY()<br><br>public: <br>    \/\/ Sets default values for this component's properties<br>    UFollowActorComponent();<br><br>protected:<br>    \/\/ Called when the game starts<br>    virtual void BeginPlay() override;<br><br>public: <br>    \/\/ Called every frame<br>    virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;<br><br>    <strong>UPROPERTY(EditAnywhere)<\/strong><br><strong>    AActor * target;<\/strong><br>};<\/pre>\n\n\n\n<ol><li>Then, in the&nbsp;FollowActorComponent.cpp&nbsp;file, in the&nbsp;TickComponent&nbsp;function, look into the available constructors under the&nbsp;FRotationMatrix&nbsp;class. A bunch of constructors&nbsp;are available that will let you specify a rotation for an object (from stock position) by reorienting one or more of the&nbsp;<em>X<\/em>-,&nbsp;<em>Y<\/em>-, or&nbsp;<em>Z<\/em>-axes, named with the&nbsp;FRotationMatrix::Make*()&nbsp;pattern.<\/li><li>Assuming you have a default stock orientation for your actor (with Forward facing down the&nbsp;<em>+X<\/em>-axis, and up facing up the&nbsp;<em>+Z<\/em>-axis), find the vector from the follower to the object they want to follow, as shown in this piece of code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ Called every frame<br>void UFollowActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)<br>{<br>    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);<br><br><strong>    FVector toFollow = target-&gt;GetActorLocation() - GetOwner()-&gt;GetActorLocation();<\/strong><br><br><strong>    FMatrix rotationMatrix = FRotationMatrix::MakeFromXZ(toFollow, GetOwner()-&gt;GetActorUpVector());<\/strong><br><br><strong>    GetOwner()-&gt;SetActorRotation(rotationMatrix.Rotator());<\/strong><br><br>}<\/pre>\n\n\n\n<ol><li>Compile your script and assign the&nbsp;Target&nbsp;property inside of the&nbsp;Follow Actor Component&nbsp;from the&nbsp;Details&nbsp;tab. This can be done using the eyedropper button to the right of the property or by using the drop-down list:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/37b4eeb3-2998-4d99-b3cf-0d6e219be4d6.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>If all went well, you should see the actor rotate correctly to face the target:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/c28f774e-1745-4d24-bcd7-8d7986021a0c.png\" alt=\"\"\/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>Getting one object to look at another, with a desired up vector, can be done by calling the correct function, depending on your object&#8217;s stock orientation. Usually, you want to reorient the&nbsp;<em>X<\/em>-axis (Forward), while specifying either the&nbsp;<em>Y<\/em>-axis (Right) or&nbsp;<em>Z<\/em>-axis (Up) vectors (FRotationMatrix::MakeFromXY()). For example, to make an actor look along a&nbsp;lookAlong&nbsp;vector, with its right side facing right, we&#8217;d construct and set&nbsp;FRotationMatrix&nbsp;for it, as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FRotationMatrix rotationMatrix = FRotationMatrix::MakeFromXY( \n lookAlong, right ); \nactor->SetActorRotation( rotationMatrix.Rotator() ); <\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">GameplayAbilities API \u2013 triggering an actor&#8217;s gameplay abilities with game controls<\/h1>\n\n\n\n<p>The&nbsp;<strong>GameplayAbilities<\/strong>&nbsp;API can be used to attach C++ functions to invoke on certain button pushes, triggering the game unit to exhibit its abilities during play in response to keystroke events. In this recipe, we will show you how to do that.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Enumerate and describe your game character&#8217;s abilities. You will need to know what your character does in response to key events to code in this recipe.<\/p>\n\n\n\n<p>There are several objects that we need to use here; they are as follows:<\/p>\n\n\n\n<ul><li>The&nbsp;UGameplayAbility&nbsp;class\u2014this is needed to derive the C++ class instances of the&nbsp;UGameplayAbility&nbsp;class, with one derivative class for each ability:<\/li><li>Define what each ability does in&nbsp;.h&nbsp;and&nbsp;.cpp&nbsp;by overriding the available functions, such as&nbsp;UGameplayAbility::ActivateAbility,&nbsp;UGameplayAbility::InputPressed,&nbsp;UGameplayAbility::CheckCost,&nbsp;UGameplayAbility::ApplyCost,&nbsp;UGameplayAbility::ApplyCooldown, and so on<\/li><li>GameplayAbilitiesSet&nbsp;is a&nbsp;DataAsset&nbsp;derivative object that contains a series of enum&#8217;d command values, and blueprints of the corresponding&nbsp;UGameplayAbility&nbsp;derivative classes that define the behavior for that particular input command. Each GameplayAbility is kicked off by a keystroke or mouse-click, which is set in&nbsp;DefaultInput.ini.<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<p>In the following code, we&#8217;ll implement a&nbsp;UGameplayAbility&nbsp;derivative called&nbsp;UGameplayAbility_Attack&nbsp;for a&nbsp;Warrior&nbsp;class object. We&#8217;ll attach this gameplay functionality to the input command string&nbsp;Ability1, which we&#8217;ll activate on the left-mouse button-click:<\/p>\n\n\n\n<ol><li>Open up your&nbsp;.Build.cs&nbsp;file (in our case,&nbsp;Chapter_11.Build.cs) and add the following dependencies:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">using UnrealBuildTool;<br><br>public class Chapter_11 : ModuleRules<br>{<br>    public Chapter_11(ReadOnlyTargetRules Target) : <br>    base(Target)<br>    {<br>        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;<br>    <br>        PublicDependencyModuleNames.AddRange(new string[] {<br>        \"Core\", \"CoreUObject\", \"Engine\", \"InputCore\" });<br>        <strong>PublicDependencyModuleNames.AddRange(new string[] {  <br>        \"GameplayAbilities\", \"GameplayTags\", \"GameplayTasks\" });<\/strong><br><br>        PrivateDependencyModuleNames.AddRange(new string[] { });<br>    }<br>}<\/pre>\n\n\n\n<ol><li>Compile your code.<\/li><li>From the Unreal Editor, go to&nbsp;Settings | Plugins.<\/li><li>From the menu that pops up, search for&nbsp;GameplayAbilities&nbsp;and check it. You&#8217;ll get a message asking if you are sure. Click on the&nbsp;Yes&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/fb27ba3b-6389-4a08-9651-614f0d31f7dc.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Afterwards, click on the&nbsp;Restart Now&nbsp;button. The classes should be added to your project correctly.<\/li><li>Now, access the&nbsp;Add C++ Class&nbsp;wizard by selecting from the Content Browser&nbsp;Add New | New C++ Class&#8230;&nbsp;and check the&nbsp;Show All Classes&nbsp;option. From there, type in&nbsp;gameplayability&nbsp;and select the base&nbsp;GameplayAbility&nbsp;class to base our new class on:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/b731ae0b-66a3-40f4-a9d8-dae61e50aafb.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Give the new gameplay ability a name of&nbsp;GameplayAbility_Attack&nbsp;and press&nbsp;Create Class.<\/li><li>At the very least, you want to override the following:<\/li><\/ol>\n\n\n\n<ul><li>The&nbsp;UGameplayAbility_Attack::CanActivateAbility&nbsp;member function to indicate when the actor is allowed to invoke the ability.<\/li><li>The&nbsp;UGameplayAbility_Attack::CheckCost&nbsp;function to indicate whether the player can afford to use an ability or not. This is extremely important because if this returns false, ability invocation should fail.<\/li><li>The&nbsp;UGameplayAbility_Attack::ActivateAbility&nbsp;member function to write the code that the&nbsp;Warrior&nbsp;is to execute when their&nbsp;Attack&nbsp;ability is activated.<\/li><li>The&nbsp;UGameplayAbility_Attack::InputPressed&nbsp;member function and to respond to the key input event assigned to the ability:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"Abilities\/GameplayAbility.h\"<br>#include \"GameplayAbility_Attack.generated.h\"<br><br>UCLASS()<br>class CHAPTER_11_API UGameplayAbility_Attack : public UGameplayAbility<br>{<br>  GENERATED_BODY()<br><br><strong>        \/** Returns true if this ability can be activated<br>        right now. Has no side effects *\/<\/strong><br><strong>        virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags = nullptr, const FGameplayTagContainer* TargetTags = nullptr, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const {<\/strong><br><strong>        UE_LOG(LogTemp, Warning, TEXT(\"ability_attack <br>        CanActivateAbility!\"));<\/strong><br><strong>        return true;<\/strong><br><strong>    }<\/strong><br><br><strong>    \/** Checks cost. returns true if we can pay for the<br>    ability. False if not *\/<\/strong><br><strong>    virtual bool CheckCost(const FGameplayAbilitySpecHandle Handle, <br>    const FGameplayAbilityActorInfo* ActorInfo, OUT <br>    FGameplayTagContainer* OptionalRelevantTags = nullptr) const {<\/strong><br><strong>        UE_LOG(LogTemp, Warning, TEXT(\"ability_attack CheckCost!\"));<\/strong><br><strong>        return true;<\/strong><br><strong>        \/\/return Super::CheckCost( Handle, ActorInfo, <br>        \/\/OptionalRelevantTags );<\/strong><br><strong>    }<\/strong><br><br><strong>    virtual void ActivateAbility(const FGameplayAbilitySpecHandle <br>    Handle,<\/strong><br><strong>        const FGameplayAbilityActorInfo* ActorInfo, const <br>        FGameplayAbilityActivationInfo ActivationInfo,<\/strong><br><strong>        const FGameplayEventData* TriggerEventData)<\/strong><br><strong>    {<\/strong><br><strong>        UE_LOG(LogTemp, Warning, TEXT(\"Activating <br>        ugameplayability_attack().. swings weapon!\"));<\/strong><br><strong>        Super::ActivateAbility(Handle, ActorInfo, ActivationInfo,  <br>        TriggerEventData);<\/strong><br><strong>    }<\/strong><br><br><strong>    \/** Input binding stub. *\/<\/strong><br><strong>    virtual void InputPressed(const FGameplayAbilitySpecHandle <br>    Handle, const FGameplayAbilityActorInfo* ActorInfo, const <br>    FGameplayAbilityActivationInfo ActivationInfo) {<\/strong><br><strong>        UE_LOG(LogTemp, Warning, TEXT(\"ability_attack <br>        inputpressed!\"));<\/strong><br><strong>        Super::InputPressed(Handle, ActorInfo, ActivationInfo);<\/strong><br><strong>    }<\/strong><br>  <br>};<\/pre>\n\n\n\n<ol><li>Derive a Blueprint class from your&nbsp;UGameplayAbility_Attack&nbsp;object inside the UE4 Editor.<\/li><li>Inside the Editor, navigate to&nbsp;Content Browser&nbsp;and create a&nbsp;GameplayAbilitiesSet&nbsp;object by&nbsp;doing the following:<\/li><\/ol>\n\n\n\n<ul><li>Right-clicking on&nbsp;Content Browser&nbsp;and selecting&nbsp;Miscellaneous&nbsp;|&nbsp;Data Asset:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/777500fc-befc-4e6b-b1ca-8924737f7ecf.png\" alt=\"\"\/><\/figure>\n\n\n\n<ul><li>In the dialog box that follows, select&nbsp;GameplayAbilitySet&nbsp;for the&nbsp;Data Asset&nbsp;Class:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/90023d90-6b67-4cc4-896a-ace1d96ee8c5.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>In fact, the&nbsp;GameplayAbilitySet&nbsp;object is a&nbsp;UDataAsset&nbsp;derivative. It is located in&nbsp;GameplayAbilitySet.h&nbsp;and contains a single member function,&nbsp;GameplayAbilitySet::GiveAbilities(), which I strongly recommend you not to use for reasons listed in a later step.<\/p>\n\n\n\n<ol><li>Name your&nbsp;GameplayAbilitySet&nbsp;data asset something related to the&nbsp;WarriorAbilitySet&nbsp;object so that we know to put it into the&nbsp;Warrior&nbsp;class (for example,&nbsp;WarriorAbilitySet).<\/li><li>Double-click to open and edit the new&nbsp;WarriorAbilitySet&nbsp;Data Asset. Stack in a list of&nbsp;GameplayAbility&nbsp;class derivative Blueprints by clicking&nbsp;+&nbsp;on the&nbsp;TArray&nbsp;object inside of it. Your&nbsp;UGameplayAbility_Attack&nbsp;object must appear in the dropdown:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/01c90d63-775f-4669-8d74-a9e01192e4f7.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>We now need to create a&nbsp;Character&nbsp;class-derived object so that we can contain this ability set. In this example, we will call this class&nbsp;Warrior.<\/li><li>Add a&nbsp;UPROPERTY UGameplayAbilitySet* gameplayAbilitySet&nbsp;member to your&nbsp;Warrior&nbsp;class:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"GameFramework\/Character.h\"<br><strong>#include \"GameplayAbilitySet.h\"<\/strong><br><strong>#include \"AbilitySystemInterface.h\"<\/strong><br>#include \"Warrior.generated.h\"<br><br><strong>#define FS(x,...) FString::Printf( TEXT( x ), __VA_ARGS__ )<\/strong><br><br>UCLASS()<br>class CHAPTER_11_API AWarrior : public ACharacter<strong>, public IAbilitySystemInterface<\/strong><br>{<br>    GENERATED_BODY()<br><br>public:<br>    \/\/ Sets default values for this character's properties<br>    AWarrior();<br><br>protected:<br>    \/\/ Called when the game starts or when spawned<br>    virtual void BeginPlay() override;<br><br>public: <br>    \/\/ Called every frame<br>    virtual void Tick(float DeltaTime) override;<br><br>    \/\/ Called to bind functionality to input<br>    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;<br><br><strong>    \/\/ Lists key triggers for various abilities for the <br>    \/\/ player.<\/strong><br><strong>    \/\/ Selects an instance of UGameplayAbilitySet (which is a      \/\/    \\<br>    UDataAsset derivative<\/strong><br><strong>    \/\/ that you construct in the Content Browser).<\/strong><br><strong>    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category =<br>    Stats)<\/strong><br><strong>    UGameplayAbilitySet* gameplayAbilitySet;<\/strong><br><br><strong>    \/\/ The AbilitySystemComponent itself<\/strong><br><strong>    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category =<br>    Stats)<\/strong><br><strong>    UAbilitySystemComponent* AbilitySystemComponent;<\/strong><br><br><strong>    \/\/ IAbilitySystemInterface implementation:<\/strong><br><strong>    virtual UAbilitySystemComponent* GetAbilitySystemComponent() const { return AbilitySystemComponent; }<\/strong><br><br>};<br><br><\/pre>\n\n\n\n<p>Ensure that your&nbsp;Actor&nbsp;class derivative also derives from the&nbsp;UAbilitySystemInterface&nbsp;interface. This is extremely important so that calls to&nbsp;(Cast&lt;IAbilitySystemInterface&gt;(yourActor))-&gt;GetAbilitySystemComponent()&nbsp;succeed.<\/p>\n\n\n\n<ol><li>Create a Blueprint of the&nbsp;Warrior&nbsp;class and set the&nbsp;Gameplay Ability Set&nbsp;to the&nbsp;Warrior Ability Set&nbsp;we created earlier, and set the&nbsp;Ability System Component&nbsp;to the&nbsp;Ability System Component:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/16747445-09a2-4b0e-b317-85c07b104892.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>If you are unable to see the&nbsp;Ability System Component, close and reopen the Blueprint.<\/p>\n\n\n\n<ol><li>Once finished, assign&nbsp;MyWarrior&nbsp;as the&nbsp;Default Pawn Class&nbsp;of your Game Mode.<\/li><li>Compile, run, and select-in&nbsp;WarriorAbilitySet&nbsp;as it sits in&nbsp;Content Browser&nbsp;(created in Steps 5 to 7) of the abilities of which this&nbsp;Warrior&nbsp;is capable.<\/li><li>Some time after the construction of your actor, call&nbsp;gameplayAbilitySet-&gt;GiveAbilities( abilitySystemComponent );&nbsp;or enter a loop, as shown in the following step where you invoke&nbsp;abilitySystemComponent-&gt;GiveAbility()&nbsp;for each ability listed in your&nbsp;gameplayAbilitySet.<\/li><li>Write an override for&nbsp;AWarrior::SetupPlayerInputComponent( UInputComponent* Input )&nbsp;to connect the input controller to the Warrior&#8217;s&nbsp;GameplayAbility&nbsp;activations. After doing so, iterate over each&nbsp;GameplayAbility&nbsp;listed in your&nbsp;GameplayAbilitySet&#8217;s&nbsp;Abilities&nbsp;group:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"AbilitySystemComponent.h\"<br><br>\/\/ ...<br><br>\/\/ Called to bind functionality to input<br>void AWarrior::SetupPlayerInputComponent(UInputComponent* Input)<br>{<br>    Super::SetupPlayerInputComponent(Input);<br><br>    \/\/ Connect the class's AbilitySystemComponent <br>    \/\/ to the actor's input component <br>    AbilitySystemComponent-&gt;BindToInputComponent(Input);<br><br>    \/\/ Go thru each BindInfo in the gameplayAbilitySet. <br>    \/\/ Give &amp; try and activate each on the <br>    \/\/ AbilitySystemComponent. <br>    for (const FGameplayAbilityBindInfo&amp; BindInfo :<br>        gameplayAbilitySet-&gt;Abilities)<br>    {<br><br>        FGameplayAbilitySpec spec(<br>            \/\/ Gets you an instance of the UClass <br>            BindInfo.GameplayAbilityClass-&gt;<br>            GetDefaultObject&lt;UGameplayAbility&gt;(),<br>            1, (int32)BindInfo.Command);<br><br>        \/\/ STORE THE ABILITY HANDLE FOR LATER INVOKATION <br>        \/\/ OF THE ABILITY <br>        FGameplayAbilitySpecHandle abilityHandle =<br>            AbilitySystemComponent-&gt;GiveAbility(spec);<br><br>        \/\/ The integer id that invokes the ability <br>        \/\/ (ith value in enum listing) <br>        int32 AbilityID = (int32)BindInfo.Command;<br><br>        \/\/ CONSTRUCT the inputBinds object, which will <br>        \/\/ allow us to wire-up an input event to the <br>        \/\/ InputPressed() \/ InputReleased() events of <br>        \/\/ the GameplayAbility. <br>        FGameplayAbilityInputBinds inputBinds(<br>            \/\/ These are supposed to be unique strings that <br>            \/\/ define what kicks off the ability for the actor        <br>            \/\/ instance. <br>            \/\/ Using strings of the format <br>            \/\/ \"ConfirmTargetting_Player0_AbilityClass\" <br>            FS(\"ConfirmTargetting_%s_%s\", *GetName(),<br>                *BindInfo.GameplayAbilityClass-&gt;GetName()),<br>            FS(\"CancelTargetting_%s_%s\", *GetName(),<br>                *BindInfo.GameplayAbilityClass-&gt;GetName()),<br>            \"EGameplayAbilityInputBinds\", \/\/ The name of the<br>            \/\/ ENUM that has the abilities listing<br>            \/\/ (GameplayAbilitySet.h). <br>            AbilityID, AbilityID<br>        );<br>        \/\/ MUST BIND EACH ABILITY TO THE INPUTCOMPONENT,<br>        \/\/ OTHERWISE THE ABILITY CANNOT \"HEAR\" INPUT EVENTS. <br>        \/\/ Enables triggering of InputPressed() \/ <br>        \/\/ InputReleased() events, which you can in-turn use <br>        \/\/ to call <br>        \/\/ TryActivateAbility() if you so choose. <br>        AbilitySystemComponent-&gt;BindAbilityActivationToInputComponent(<br>            Input, inputBinds<br>        );<br><br>        \/\/ Test-kicks the ability to active state. <br>        \/\/ You can try invoking this manually via your <br>        \/\/ own hookups to keypresses in this Warrior class <br>        \/\/ TryActivateAbility() calls ActivateAbility() if <br>        \/\/ the ability is indeed invokable at this time <br>        \/\/ according to rules internal to the Ability's class <br>        \/\/ (such as cooldown is ready and cost is met) <br>        AbilitySystemComponent-&gt;TryActivateAbility(<br>            abilityHandle, 1);<br>    }<br>}<br><br><br><\/pre>\n\n\n\n<ol><li>Compile your code and then play the game:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/7cad0887-cbad-49f8-966b-83e6fc2d9f0d.png\" alt=\"\"\/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>You must subclass and link in a set of&nbsp;UGameplayAbility&nbsp;objects to your actor&#8217;s&nbsp;UAbilitySystemComponent&nbsp;object through a series of calls to&nbsp;UAbilitySystemComponent::GiveAbility( spec )&nbsp;with appropriately constructed&nbsp;FGameplayAbilitySpec&nbsp;objects. What this does is deck out your actor with this bunch of&nbsp;GameplayAbilities. The functionality of each&nbsp;UGameplayAbility,&nbsp;as well as its cost, cooldown, and activation, is all neatly contained within the&nbsp;UGameplayAbility&nbsp;class derivative that you will construct.<\/p>\n\n\n\n<p>Do not use&nbsp; the&nbsp;GameplayAbilitySet::GiveAbilities()&nbsp;member function because it doesn&#8217;t give you access to the set of&nbsp;FGameplayAbilitySpecHandle&nbsp;objects that you actually need later&nbsp;to&nbsp;bind and invoke the ability to an input component.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">There&#8217;s more&#8230;<\/h1>\n\n\n\n<p>You&#8217;ll want to carefully code in a bunch of the other functions that are available in the&nbsp;GameplayAbility.h&nbsp;header file, including implementations for the following:<\/p>\n\n\n\n<ul><li>SendGameplayEvent: This is a function to notify GameplayAbility that some general gameplay event has happened.<\/li><li>CancelAbility: This is a function to stop an ability&#8217;s usage midway through, and to give the ability an interrupted state.<\/li><li>Keep in mind that there are a bunch of existing&nbsp;UPROPERTY&nbsp;specifiers near the bottom of the&nbsp;UGameplayAbility&nbsp;class declaration that either activate or cancel the ability upon addition or removal of certain&nbsp;GameplayTags. See the following&nbsp;<em>GameplayTags API \u2013 attaching GameplayTags to an actor<\/em>&nbsp;recipe for more details.<\/li><li>There are a bunch more! Explore the API and implement those functions you find to be useful in your code.<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">See also<\/h1>\n\n\n\n<ul><li>The&nbsp;GameplayAbilities&nbsp;API is a rich and nicely interwoven series of objects and functions. Explore&nbsp;GameplayEffects,&nbsp;GameplayTags, and&nbsp;GameplayTasks&nbsp;and how they integrate with the&nbsp;UGameplayAbility&nbsp;class to fully explore the functionality the library has to offer. You can read more about the API here:&nbsp;<a href=\"https:\/\/api.unrealengine.com\/INT\/API\/Plugins\/GameplayAbilities\/index.html\">https:\/\/api.unrealengine.com\/INT\/API\/Plugins\/GameplayAbilities\/index.html<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>FRotationMatrix\u00a0offers matrix construction using a seri [&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\/3123"}],"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=3123"}],"version-history":[{"count":2,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3123\/revisions"}],"predecessor-version":[{"id":3338,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3123\/revisions\/3338"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}