document.write("
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Dandelion/Sandbox/Abilities/InputActionGameplayAbility.h"
#include "IAGA_PlayerMove.generated.h"
namespace EPathFollowingResult
{
enum Type : int;
}
class UAbilityTask_MoveCharacterToCursor;
class UAbilityTask_FollowCursor;
/**
* Custom IAGA that implements player movement. Has two phases.
* - Phase 1: While the mouse button is held down, follow the cursor using a UAbilityTask_FollowCursor.
* - Phase 2: When the mouse button is released, use the nav system to move to the point that was under the cursor when
* released using a UAbilityTask_MoveCharacterToCursor.
* When the target point is reached in Phase 2, end the GA. This GA cannot be restarted during Phase 1.
* TODO: What happens if there isn't a valid point under the cursor upon release? Can the release callback come before ActivateAbility?
*/
UCLASS()
class DANDELION_API UIAGA_PlayerMove : public UInputActionGameplayAbility
{
GENERATED_BODY()
/**
* Sets the response on pressed mode to cancel so that new move inputs will override current move targets/behavior
* and on release mode to Custom so the ability will only end when the final move to point is reached.
*/
UIAGA_PlayerMove();
/**
* Custom restart handler that prevents this GA from being restarted by an input press unless it is in Phase 2 with
* an active UAbilityTask_MoveCharacterToCursor. This is to prevent constant re-triggering of the GA during Phase 1.
* TODO: Probably a better way to handle this would be to unbind from InputPressed on the ASC so this isn't getting
* called every frame while the button is held down.
* @param Handle Handle of the GameplayAbilitySpec that woudl be restarted on success.
* @param ActorInfo Actor Info for the activation of this ability.
* @param ActivationInfo Networking data related to the activation of this ability.
* @return
*/
virtual bool CanRestartAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo& ActivationInfo
) override;
protected:
/**
* Stops any currently ongoing movement and starts a follow cursor task. If the target location is reached, end this
* ability.
* @param Handle Handle of the GameplayAbilitySpec that was activated.
* @param ActorInfo Actor Info for the activation of this ability.
* @param ActivationInfo Networking data related to the activation of this ability.
* @param TriggerEventData The FGameplayEventData that accompanied the activation of this ability.
*/
virtual void ActivateAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData
) override;
/**
* Cancels FollowCursorAbilityTask and MoveCharacterToCursorAbilityTask if they are currently active.
* @param Handle Handle of the GameplayAbilitySpec that was ended.
* @param ActorInfo Actor Info for the ending of this ability.
* @param ActivationInfo Networking data that was originally related to the activation of this ability.
* @param bReplicateCancelAbility Whether the cancel of this ability needs to be replicated to the client/server.
*/
virtual void CancelAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateCancelAbility
) override;
/**
* Ends FollowCursorAbilityTask and MoveCharacterToCursorAbilityTask if they are currently active. They should have
* been cleaned up already, however.
* @param Handle Handle of the GameplayAbilitySpec that was ended.
* @param ActorInfo Actor Info for the ending of this ability.
* @param ActivationInfo Networking data that was originally related to the activation of this ability.
* @param bReplicateEndAbility Whether the ending of this ability needs to be replicated to the client/server.
* @param bWasCancelled Whether this ability was cancelled or if it ended naturally.
*/
virtual void EndAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateEndAbility,
bool bWasCancelled
) override;
/**
* When the InputID is released, stop the ongoing follow cursor task (if valid), and raise the GameplayTag for the
* MoveVFX Gameplay Cue.
* @param Handle Handle of the GameplayAbilitySpec whose InputID was released.
* @param ActorInfo Actor Info for the release of the input of this ability.
* @param ActivationInfo Networking data that was originally related to the activation of this ability.
*/
virtual void HandleInputReleased_Implementation(
const FGameplayAbilitySpecHandle& Handle,
const FGameplayAbilityActorInfo& ActorInfo,
const FGameplayAbilityActivationInfo& ActivationInfo
) override;
private:
/**
* The GameplayTag for the MoveVFX GameplayCue.
*/
UPROPERTY(
EditDefaultsOnly,
DisplayName="Move VFX Cue Tag",
meta=(AllowPrivateAccess=true, Categories="GameplayCue.VFX")
)
FGameplayTag MoveVFXCueTag;
/**
* Owned reference of the UAbilityTask_FollowCursor to ensure cleanup when this Ability ends.
*/
UPROPERTY(Transient)
TObjectPtr<UAbilityTask_FollowCursor> FollowCursorAbilityTask;
/**
* Owned reference of the MoveCharacterToCursorAbilityTask to ensure cleanup when this Ability ends.
*/
UPROPERTY(Transient)
TObjectPtr<UAbilityTask_MoveCharacterToCursor> MoveCharacterToCursorAbilityTask;
/**
* Gets bound to the OnMoveComplete delegate on the MoveCharacterToCursorAbilityTask. If the move request to the
* NavSystem was successful, end the task and GA using EndTask/EndAbility. If it was not, cancel the task and GA
* using CancelTask/CancelAbility.
* @param PathingResultType
*/
UFUNCTION(meta=(BlueprintInternalUseOnly))
void HandleOnMoveComplete(EPathFollowingResult::Type PathingResultType);
};
IAGA_PlayerMove.h - Snippet hosted by \"Cacher\"
");