Skip to content

Instantly share code, notes, and snippets.

@mklabs
Created January 12, 2022 19:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mklabs/305a223866c5f1c506219e2df5781e7e to your computer and use it in GitHub Desktop.
Save mklabs/305a223866c5f1c506219e2df5781e7e to your computer and use it in GitHub Desktop.
Custom Actor with Ability System Component (GAS Companion 3.x, replacement for now deprecated GSCActor)

First, you need to convert the project to c++ if not done already by adding a new Actor to your game module.

We'll also use the generated class and replace the content after.

image Example: ComboGraphHost_4_27 will be replaced by your project name

Next, you'll need to slightly edit your Build.cs file for your game module (should be Source/YourProject/YourProject.Build.cs). It was generated by Unreal the first time you added a c++ class to the project.

You need for AMyAbilitySystemActor (see header and source file in this gist) to properly compile to add at the very least "GameplayAbilities" to the PublicDependencyModuleNames and "ModularGASCompanion" to PrivateDependencyModuleNames in your Build.cs file.

It should look something like:

PublicDependencyModuleNames.AddRange(new string[]
{
	"Core",
	"CoreUObject",
	"Engine",
	"InputCore",
	"GameplayAbilities",
});

PrivateDependencyModuleNames.AddRange(new string[]
{
	"ModularGASCompanion",
	"GameplayTasks",
	"GameplayTags",
});

Next we need to update the content of both the header (.h extension) and source (.cpp extension) files.

Header: MyAbilitySystemActor.h

File should be located in Source/ProjectName/Public (depending on the path you provided when first generating the file with the Editor wizard)

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/Actor.h"
#include "MyAbilitySystemActor.generated.h"

class UMGCAbilitySystemComponent;

UCLASS()
class AMyAbilitySystemActor : public AActor, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyAbilitySystemActor();

	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	UMGCAbilitySystemComponent* AbilitySystemComponent;

	/**
	* Ability System Replication Mode: How gameplay effects will be replicated to clients
	*
	* - Full: Replicate full gameplay info to all. Every GameplayEffect is replicated to every client.
	* (Recommended for Single Player games)
	* - Mixed: Only replicate minimal gameplay effect info to simulated proxies but full info to owners and autonomous proxies.
	* GameplayEffects are only replicated to the owning client. Only GameplayTags and GameplayCues are replicated to everyone.
	* (Recommended for Multiplayer on Player controlled Actors)
	* - Minimal: Only replicate minimal gameplay effect info. Note: this does not work for Owned AbilitySystemComponents (Use Mixed instead).
	* GameplayEffects are never replicated to anyone. Only GameplayTags and GameplayCues are replicated to everyone.
	* (Recommended for Multiplayer on AI controlled Actors)
	*
	* @See https://github.com/tranek/GASDocumentation#concepts-asc-rm for more information
	*/
	UPROPERTY(EditDefaultsOnly, Category="Modular GAS Companion|Ability System")
	EGameplayEffectReplicationMode ReplicationMode = EGameplayEffectReplicationMode::Minimal;

	//~ Begin IAbilitySystemInterface
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
	//~ End IAbilitySystemInterface

	//~ Begin AActor Interface
	virtual void PostInitProperties() override;
	//~ End AActor Interface
};

Note: You can add the macro PROJECTNAME_API that was first generated right after the class keyword, but it's not strictly necessary for Blueprints to subclass it.

Source: MyAbilitySystemActor.cpp

#include "MyAbilitySystemActor.h"

#include "Abilities/MGCAbilitySystemComponent.h"

// Sets default values
AMyAbilitySystemActor::AMyAbilitySystemActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	// Set this actor to replicate like a Pawn would
	bReplicates = true;

	// Set Ability System Companion with GAS Companion subclass
	AbilitySystemComponent = CreateDefaultSubobject<UMGCAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
	AbilitySystemComponent->SetIsReplicated(true);

}

UAbilitySystemComponent* AMyAbilitySystemActor::GetAbilitySystemComponent() const
{
	return AbilitySystemComponent;
}

void AMyAbilitySystemActor::PostInitProperties()
{
	Super::PostInitProperties();
	if (AbilitySystemComponent)
	{
		AbilitySystemComponent->SetReplicationMode(ReplicationMode);
	}
}

Back to the editor, you can now implement a Blueprint child class of our new Actor:

image

You should see in the Components window the Ability System Component, child of MGCAbilitySystemComponent, which lets you access the Abilities related properties like you would with ModularPawn or ModularCharacter.

image

In this quick test, I also added 4 Text Render component to visualize the Health attribute.

image

And added GSCCoreComponent to the actor (the exposed API and events should work the same), mainly to be able to easily react on attribute changes to update the text component with the new Health values.

image

The Event Graph itself to hook up text renders text with the health attribute:

image

The result when applying a gameplay effect that modify the Health value (here, applying a GE to the Test Actor's ASC when I'm hitting a debug input in my character BP)

test_abilitysystem_actor_1280


That's it! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment