- Click on File | Add C++ Class.... Choose to derive from GameplayTask. To do so, you must first tick Show All Classes, and then type gameplaytask into the filter box. Click on Next:
- Name your C++ class (something like GameplayTask_TaskName is the convention), then add the class to your project. The example spawns a particle emitter and is called GameplayTask_CreateParticles:
- Once your GameplayTask_CreateParticles.h and .cpp pair are created, navigate to the .h file and update the class to the following:
#pragma once
#include "CoreMinimal.h"
#include "GameplayTask.h"
#include "Particles/ParticleSystem.h"
#include "GameplayTask_CreateParticles.generated.h"
/**
*
*/
UCLASS()
class CHAPTER_11_API UGameplayTask_CreateParticles : public UGameplayTask
{
GENERATED_BODY()
public:
virtual void Activate();
// A static constructor for an instance of a
// UGameplayTask_CreateEmitter instance,
// including args of (what class of emitter, where to
// create it).
UFUNCTION(BlueprintCallable, Category = "GameplayTasks", meta = (AdvancedDisplay = "TaskOwner", DefaultToSelf = "TaskOwner", BlueprintInternalUseOnly = "TRUE"))
static UGameplayTask_CreateParticles* ConstructTask(
TScriptInterface<IGameplayTaskOwnerInterface> TaskOwner,
UParticleSystem* particleSystem,
FVector location);
UParticleSystem* ParticleSystem;
FVector Location;
};
- Then, implement the GameplayTask_CreateParticles.cpp file, as follows:
#include "GameplayTask_CreateParticles.h"
#include "Kismet/GameplayStatics.h"
// Like a constructor.
UGameplayTask_CreateParticles* UGameplayTask_CreateParticles::ConstructTask(
TScriptInterface<IGameplayTaskOwnerInterface> TaskOwner,
UParticleSystem* particleSystem,
FVector location)
{
UGameplayTask_CreateParticles* task =
NewTask<UGameplayTask_CreateParticles>(TaskOwner);
// Fill fields
if (task)
{
task->ParticleSystem = particleSystem;
task->Location = location;
}
return task;
}
void UGameplayTask_CreateParticles::Activate()
{
Super::Activate();
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(),
ParticleSystem, Location);
}
- Open up your Warrior.h file and add the following interface to the class definition:
UCLASS()
class CHAPTER_11_API AWarrior : public ACharacter, public IAbilitySystemInterface, public IGameplayTaskOwnerInterface
{
GENERATED_BODY()
- Afterwards, add the following new properties to it:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
UGameplayTasksComponent* GameplayTasksComponent;
// This is the particleSystem that we create with the
// GameplayTask_CreateParticles object.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
UParticleSystem* particleSystem;
- Below that, add the following function definitions for the GameplayTaskOwnerInterface:
// <GameplayTaskOwnerInterface>
virtual UGameplayTasksComponent* GetGameplayTasksComponent(const
UGameplayTask& Task) const { return GameplayTasksComponent; }
// This gets called both when task starts and when task gets
// resumed.
// Check Task.GetStatus() if you want to differentiate.
virtual void OnTaskActivated(UGameplayTask& Task) { }
virtual void OnTaskDeactivated(UGameplayTask& Task) { }
virtual AActor* GetOwnerActor(const UGameplayTask* Task) const {
return Task->GetOwnerActor(); // This will give us the
// accurate answer for the Task..
}
// </End GameplayTaskOwnerInterface>
- Afterwards, go to the Warrior.cpp file and update the class constructor to the following:
AWarrior::AWarrior()
{
// Set this character to call Tick() every frame. You can
// turn this off to improve performance if you don't need
// it.
PrimaryActorTick.bCanEverTick = true;
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>
("UAbilitySystemComponent");
GameplayTasksComponent = CreateDefaultSubobject<UGameplayTasksComponent>
("UGameplayTasksComponent");
}
- Save your scripts, return to the Unreal Editor, and compile your code. Once compiled, open your Actor class derivative (MyWarrior) and then scroll down to the Stats section and set the Particle System property to something you'd like to see, for instance, the P_Fire option if you included the sample content when you created your project:
- Which is available in the Full Blueprint Editor in the Components drop-down of the Components tab in the Blueprint editor. Add GameplayTasksComponent to
- Create and add an instance of your GameplayTask inside your Actor derivative (MyWarrior) instance using the following code:
UGameplayTask_CreateParticles* task =
UGameplayTask_CreateParticles::ConstructTask(this,
particleSystem, FVector(200.f, 0.f, 200.f));
if (GameplayTasksComponent && task)
{
GameplayTasksComponent->AddTaskReadyForActivation(*task);
}
This code runs anywhere in your Actor class derivative, any time after GameplayTasksComponent is initialized (any time after PostInitializeComponents()).
- Compile your code. Set your level to use MyWarrior as the Default Pawn Type and when the game starts, you should notice that the particle plays: