void UAblAbilityTaskRaycastValidator::Validate(const TWeakObjectPtr<UAblAbilityTaskValidatorContext>& Context, const TWeakObjectPtr<const UAblAbilityTask>& Task) const { const UAblRayCastQueryTask* RaycastTask = CastChecked<const UAblRayCastQueryTask>(Task.Get()); if (!RaycastTask->GetFireEvent() && !RaycastTask->GetCopyResultsToContext()) { Context->AddWarning(LOCTEXT("AbilityValidatorRayCastNoOutput", "Raycast Task is set to not fire its event or copy its results to the context. This Task won't be able to do anything with its results.")); } }
void UAblAbilityLengthValidator::Validate(const TWeakObjectPtr<UAblAbilityTaskValidatorContext>& Context, const TWeakObjectPtr<const UAblAbilityTask>& Task) const { const float AbilityLength = Context->GetAbility()->GetLength(); const TArray<UAblAbilityTask*>& AllTasks = Context->GetAbility()->GetTasks(); float LastTaskEndTime = 0.0f; for (const UAblAbilityTask* AbilityTask : AllTasks) { if (AbilityTask->GetEndTime() > AbilityLength) { FText WarningMessage = FText::Format(LOCTEXT("AbilityValidatorTaskTooLong", "Task {0} extends past the length of the ability. Is this intended?"), AbilityTask->GetTaskName()); Context->AddWarning(WarningMessage); } LastTaskEndTime = FMath::Max(AbilityTask->GetEndTime(), LastTaskEndTime); } if (AbilityLength - LastTaskEndTime > KINDA_SMALL_NUMBER) { FText WarningMessage = FText::FormatOrdered(LOCTEXT("AbilityValidatorEmptySpace", "There is empty space in the timeline. The last task finishes at {0} but the ability has a length of {1}. Is this intended?"), LastTaskEndTime, AbilityLength); Context->AddWarning(WarningMessage); } }