document.write("
// Fill out your copyright notice in the Description page of Project Settings. UAbilityTask_FollowCursor::UAbilityTask_FollowCursor() { bTickingTask = true; } UAbilityTask_FollowCursor* UAbilityTask_FollowCursor::FollowCursor( UDandelionGameplayAbility* OwningAbility, const FName TaskInstanceName, const float StopDistance ) { UAbilityTask_FollowCursor* NewTaskInstance = NewAbilityTask<UAbilityTask_FollowCursor>(OwningAbility, TaskInstanceName); NewTaskInstance->TargetLocation = FVector::ZeroVector; if (StopDistance < 0.f) { UE_LOG( LogGameplayTasks, Warning, TEXT("%s: Tried to instantiate a new MoveToCursorTask with an invalid StopDistance: %f."), *GetFullNameSafe(NewTaskInstance), StopDistance ) } NewTaskInstance->StopDistance = FMath::Max(0.f, StopDistance); APawn* AvatarPawn = OwningAbility->TryCastAvatarActorFromActorInfo<APawn>(); if (!ensure(IsValid(AvatarPawn))) { UE_LOG( LogGameplayTasks, Error, TEXT("%s: Tried to instantiate a new MoveToCursorTask without a valid avatar Pawn."), *GetFullNameSafe(NewTaskInstance) ) return NewTaskInstance; } NewTaskInstance->PlayerPawn = AvatarPawn; ADandelionPlayerController* AvatarController = AvatarPawn->GetController<ADandelionPlayerController>(); if (!ensure(IsValid(AvatarController))) { UE_LOG( LogGameplayTasks, Error, TEXT("%s: Tried to instantiate a new MoveTo task without a valid avatar PlayerController."), *GetFullNameSafe(NewTaskInstance) ) return NewTaskInstance; } NewTaskInstance->PlayerController = AvatarController; return NewTaskInstance; } void UAbilityTask_FollowCursor::ExternalCancel() { if (IsValid(PlayerController)) { PlayerController->StopMovement(); } Super::ExternalCancel(); } void UAbilityTask_FollowCursor::Activate() { if (!IsValid(PlayerController)) { UE_LOG( LogGameplayTasks, Warning, TEXT("%s: Tried to Activate with an invalid avatar PlayerController."), *GetFullNameSafe(this) ) return; } PlayerController->StopMovement(); Super::Activate(); } void UAbilityTask_FollowCursor::TickTask(const float DeltaTime) { if (!IsValid(PlayerPawn)) { UE_LOG( LogGameplayTasks, Warning, TEXT("%s: Tried to TickTask with an invalid avatar Pawn."), *GetFullNameSafe(this) ) EndTask(); return; } UpdateTargetLocation(); const float XYDistance = FVector::DistXY(TargetLocation, PlayerPawn->GetActorLocation()); const FVector WorldDisplacement = TargetLocation - PlayerPawn->GetActorLocation(); if (XYDistance < StopDistance + UE_SMALL_NUMBER) { OnMoveComplete.Broadcast(); EndTask(); return; } PlayerPawn->AddMovementInput(WorldDisplacement.GetSafeNormal(), 1.0, false); Super::TickTask(DeltaTime); } void UAbilityTask_FollowCursor::UpdateTargetLocation() { FHitResult Hit; if (!PlayerController->GetHitResultUnderCursor(ECC_Visibility, true, Hit)) { UE_LOG( LogGameplayTasks, VeryVerbose, TEXT("%s: Failed to register a hit under cursor in GetTargetLocation. Using CachedDestination: %s"), *GetFullNameSafe(this), *TargetLocation.ToString() ); return; } TargetLocation = Hit.Location; }