{"id":50,"date":"2021-01-24T23:25:57","date_gmt":"2021-01-24T23:25:57","guid":{"rendered":"https:\/\/www.thegames.dev\/?p=50"},"modified":"2021-01-25T00:19:04","modified_gmt":"2021-01-25T00:19:04","slug":"making-a-custom-ability-actor-info","status":"publish","type":"post","link":"https:\/\/www.thegames.dev\/?p=50","title":{"rendered":"Making a custom Ability Actor Info"},"content":{"rendered":"\n<p>When you start getting into the power of the Gameplay Ability System, it may be needed that you want to access stuff easily in your Actor Info. The guys at Epic made this really easy to override and implement but there is a few steps. The first step that is mandatory is setting up your own Game specific UAbilitySystemGlobals. You can read that post here: <a href=\"https:\/\/www.thegames.dev\/?p=52\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.thegames.dev\/?p=52<\/a><\/p>\n\n\n\n<p>With that out of the way, let us start. <\/p>\n\n\n\n<p>The first thing you want to do is create a AbilityTypes class to hold your structs\/enums you will use in your ability system if you do not have one. In my example i have a KaosAbilityTypes.cpp and KaosAbilityTypes.h file.<\/p>\n\n\n\n<p>Next we need to create our own AbilityActorInfo derived from FGameplayAbilityActorInfo in our AbilityTypes header file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\nUSTRUCT(BlueprintType)\nstruct FKaosGameplayAbilityActorInfo : public FGameplayAbilityActorInfo\n{\n\tGENERATED_USTRUCT_BODY()\n\t\n\t\ttypedef Super FGameplayAbilityActorInfo;\n\t\n\tvirtual ~FKaosGameplayAbilityActorInfo()\n\t{\n\t}\n\n\t\/\/Our KaosAbilitySystemComponent. Should NEVER be null.\n\tUPROPERTY(BlueprintReadOnly, Category = &quot;ActorInfo&quot;)\n\tTWeakObjectPtr&lt;class UKaosAbilitySystemComponent&gt; KaosAbilitySystemComponent;\n\n\t\/\/Our KaosPawn. Often nullptr.\n\tUPROPERTY(BlueprintReadOnly, Category = &quot;ActorInfo&quot;)\n\tTWeakObjectPtr&lt;class AKaosPawn&gt; KaosPawn;\n\n\t\/\/Our Kaos Player Pawn. Often nullptr\n\tUPROPERTY(BlueprintReadOnly, Category = &quot;ActorInfo&quot;)\n\tTWeakObjectPtr&lt;class AKaosPlayerPawn&gt; KaosPlayerPawn;\n\n\t\/\/Our Kaos Player Controller. Often nullptr.\n\tUPROPERTY(BlueprintReadOnly, Category = &quot;ActorInfo&quot;)\n\tTWeakObjectPtr&lt;class AKaosPlayerController&gt; KaosPlayerController;\n\n\t\/\/Our Kaos Player State. Often nullptr.\n\tUPROPERTY(BlueprintReadOnly, Category = &quot;ActorInfo&quot;)\n\tTWeakObjectPtr&lt;class AKaosPlayerState&gt; KaosPlayerState;\n\n\tvirtual void InitFromActor(AActor* OwnerActor, AActor* AvatarActor, UAbilitySystemComponent* InAbilitySystemComponent) override;\n\n\tvirtual void SetAvatarActor(AActor* AvatarActor) override;\n\n\tvirtual void ClearActorInfo() override;\n\n\t\/\/Gets the Kaos Pawn. This is often nullptr.\n\tclass AKaosPawn* GetKaosPawn() const;\n\n\t\/\/Gets the Kaos Player Pawn. This is often nullptr.\n\tclass AKaosPlayerPawn* GetKaosPlayerPawn() const;\n\n\t\/\/Gets the Kaos Player Controller. This is often nullptr.\n\tclass AKaosPlayerController* GetKaosPlayerController() const;\n\n\t\/\/Gets the Kaos Player State. This is often nullptr.\n\tclass AKaosPlayerState* GetKaosPlayerState() const;\n};\n<\/pre><\/div>\n\n\n<p>As you can see with the above, i want to easily get my game specific Controllers, Pawn(Character) and PlayerState from the Actor Info. We have to override a few things to achieve this. We also put a typedef there so we can call Super::InitFromActor and keep it consistent with UE4 code.<\/p>\n\n\n\n<p>Now in our AbilityTypes.cpp we can start grabbing and setting our properties, as well as defining the functions we declared in our header.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\nvoid FKaosGameplayAbilityActorInfo::InitFromActor(AActor* InOwnerActor, AActor* InAvatarActor, UAbilitySystemComponent* InAbilitySystemComponent)\n{\n\tSuper::InitFromActor(InOwnerActor, InAvatarActor, InAbilitySystemComponent);\n\n\tKaosAbilitySystemComponent = Cast&lt;UKaosAbilitySystemComponent&gt;(InAbilitySystemComponent);\n\t\n        KaosPawn = Cast&lt;AKaosPawn&gt;(InAvatarActor);\n\tKaosPlayerPawn = Cast&lt;AKaosPlayerPawn&gt;(InAvatarActor);\n\n\tif (PlayerController.IsValid())\n\t{\n\t\tKaosPlayerController = Cast&lt;AKaosPlayerController&gt;(PlayerController.Get());\n\t\tKaosPlayerState = PlayerController-&gt;GetPlayerState&lt;AKaosPlayerState&gt;();\n\t}\n\telse if (KaosPawn.IsValid())\n\t{\n\t\tKaosAIController = KaosPawn-&gt;GetController&lt;AKaosAIController&gt;();\n\t}\n\n\n}\n\nvoid FKaosGameplayAbilityActorInfo::SetAvatarActor(AActor* InAvatarActor)\n{\n\tSuper::SetAvatarActor(InAvatarActor);\n}\n\nvoid FKaosGameplayAbilityActorInfo::ClearActorInfo()\n{\n\tSuper::ClearActorInfo();\n\n\tKaosPawn = nullptr;\n\tKaosPlayerPawn = nullptr;\n\tKaosPlayerState = nullptr;\n\tKaosPlayerController = nullptr;\n\tKaosAbilitySystemComponent = nullptr;\n}\n\nclass UKaosAbilitySystemComponent* FKaosGameplayAbilityActorInfo::GetKaosAbilitySystemComponent() const\n{\n\treturn KaosAbilitySystemComponent.IsValid() ? KaosAbilitySystemComponent.Get() : nullptr;\n}\n\nclass AKaosPawn* FKaosGameplayAbilityActorInfo::GetKaosPawn() const\n{\n\treturn KaosPawn.IsValid() ? KaosPawn.Get() : nullptr;\n}\n\nclass AKaosPlayerPawn* FKaosGameplayAbilityActorInfo::GetKaosPlayerPawn() const\n{\n\treturn KaosPlayerPawn.IsValid() ? KaosPlayerPawn.Get() : nullptr;\n}\n\nclass AKaosPlayerController* FKaosGameplayAbilityActorInfo::GetKaosPlayerController() const\n{\n\treturn KaosPlayerController.IsValid() ? KaosPlayerController.Get() : nullptr;\n}\n\nclass AKaosPlayerState* FKaosGameplayAbilityActorInfo::GetKaosPlayerState() const\n{\n\treturn KaosPlayerState.IsValid() ? KaosPlayerState.Get() : nullptr;\n}\n\nclass AKaosWeapon* FKaosGameplayAbilityActorInfo::GetKaosWeapon() const\n{\n\treturn GetKaosPawn() ? GetKaosPawn()-&gt;GetCurrentWeapon() : nullptr;\n}\n\nclass AKaosWeaponRanged* FKaosGameplayAbilityActorInfo::GetKaosWeaponRanged() const\n{\n\treturn GetKaosPawn() ? Cast&lt;AKaosWeaponRanged&gt;(GetKaosPawn()-&gt;GetCurrentWeapon()) : nullptr;\n}\n<\/pre><\/div>\n\n\n<p>The main bulk of the stuff, is the overridden functions, we needed to override InitActorInfo to grab the actor info required. We also overrode ClearActorInfo, so we can clear everything we had set in InitAbilityActorInfo\/SetAvatarActor.<\/p>\n\n\n\n<p>Now we need to tell the Gameplay Ability System we want to use this new Actor Info. Open your game specific AbilitySystemGlobals class header, and override the following function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\n\tvirtual FGameplayAbilityActorInfo* AllocAbilityActorInfo() const override;\n\n<\/pre><\/div>\n\n\n<p>and in the cpp file of your game specific AbilitySystemGlobals, we need to define this like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\nFGameplayAbilityActorInfo* UKaosAbilitySystemGlobals::AllocAbilityActorInfo() const\n{\n\treturn new FKaosGameplayAbilityActorInfo();\n}\n<\/pre><\/div>\n\n\n<p>Remember to replace the names with your projects names, ie FMyGameplayAbilityActorInfo, etc.<\/p>\n\n\n\n<p>To access your newly created AbilityActorInfo from within abilities, etc, you need to cast. I have shown an example below:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\nconst FKaosGameplayAbilityActorInfo* UKaosGameplayAbility::GetKaosActorInfo(const FGameplayAbilityActorInfo* InInfo)\n{\n\treturn static_cast&lt;const FKaosGameplayAbilityActorInfo*&gt;(InInfo);\n}\n<\/pre><\/div>\n\n\n<p>with the above function, which is a little wrapper, i can access specific stuff i want, like this function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: Relevant Code:; notranslate\" title=\"Relevant Code:\">\nAKaosPawn* UKaosGameplayAbility::GetKaosPawnFromAvatar(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const\n{\n\tconst FKaosGameplayAbilityActorInfo* KaosActorInfo = GetKaosActorInfo(ActorInfo);\n\treturn KaosActorInfo ? KaosActorInfo-&gt;GetKaosPawn() : nullptr;\n}\n<\/pre><\/div>\n\n\n<p>I hope this helps, and you find it useful. <\/p>\n\n\n\n<p>That is all for now \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you start getting into the power of the Gameplay Ability System, it may be needed that you want to access stuff easily in your Actor Info. The guys at Epic made this really easy to override and implement but there is a few steps. The first step that is mandatory is setting up your <a href=\"https:\/\/www.thegames.dev\/?p=50\" class=\"more-link\">&#8230;<span class=\"screen-reader-text\">  Making a custom Ability Actor Info<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-50","post","type-post","status-publish","format-standard","hentry","category-gameplay-ability-system"],"rise-blocks_total_comments":0,"rise-blocks_categories":[{"term_id":4,"name":"Gameplay Ability System","slug":"gameplay-ability-system","term_group":0,"term_taxonomy_id":4,"taxonomy":"category","description":"Unreal Engine's Gameplay Ability System (GAS)","parent":2,"count":16,"filter":"raw","cat_ID":4,"category_count":16,"category_description":"Unreal Engine's Gameplay Ability System (GAS)","cat_name":"Gameplay Ability System","category_nicename":"gameplay-ability-system","category_parent":2}],"rise-blocks_excerpt":"When you start getting into the power of the Gameplay Ability System, it may be needed that you want to access stuff easily in your Actor Info. The guys at Epic made this really easy to override and implement but there is a few steps. The first step that is mandatory is setting up your own Game specific UAbilitySystemGlobals. You..","_links":{"self":[{"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=50"}],"version-history":[{"count":9,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":68,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=\/wp\/v2\/posts\/50\/revisions\/68"}],"wp:attachment":[{"href":"https:\/\/www.thegames.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thegames.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}