void UAblRayCastQueryTask::OnTaskTick(const TWeakObjectPtr<const UAblAbilityContext>& Context, float deltaTime) const { Super::OnTaskTick(Context, deltaTime); if (IsAsyncFriendly() && UAbleSettings::IsAsyncEnabled()) { UAblRayCastQueryTaskScratchPad* ScratchPad = Cast<UAblRayCastQueryTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); if (!ScratchPad->AsyncProcessed && ScratchPad->AsyncHandle._Handle != 0) { AActor* SourceActor = m_QueryLocation.GetSourceActor(*Context.Get()); check(SourceActor); UWorld* World = SourceActor->GetWorld(); FTraceDatum Datum; if (World->QueryTraceData(ScratchPad->AsyncHandle, Datum)) { if (m_CopyResultsToContext) { CopyResultsToContext(Datum.OutHits, Context); } if (m_FireEvent) { Context->GetAbility()->OnRaycastEvent(Context.Get(), m_Name, Datum.OutHits); } ScratchPad->AsyncProcessed = true; } } } }
bool UAblRayCastQueryTask::IsDone(const TWeakObjectPtr<const UAblAbilityContext>& Context) const { if (IsAsyncFriendly() && UAbleSettings::IsAsyncEnabled()) { UAblRayCastQueryTaskScratchPad* ScratchPad = Cast<UAblRayCastQueryTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); return ScratchPad->AsyncProcessed; } else { return UAblAbilityTask::IsDone(Context); } }
void UAblSetShaderParameterTask::OnTaskStart(const TWeakObjectPtr<const UAblAbilityContext>& Context) const { Super::OnTaskStart(Context); if (!m_Value) { UE_LOG(LogAble, Warning, TEXT("No Value set for SetShaderParameter in Ability [%s]"), *Context->GetAbility()->GetDisplayName()); return; } // We need to convert our Actors to primitive components. TArray<TWeakObjectPtr<AActor>> TargetArray; GetActorsForTask(Context, TargetArray); TArray<TWeakObjectPtr<UPrimitiveComponent>> PrimitiveComponents; for (TWeakObjectPtr<AActor>& Target : TargetArray) { for (UActorComponent* Component : Target->GetComponentsByClass(UPrimitiveComponent::StaticClass())) { PrimitiveComponents.Add(Cast<UPrimitiveComponent>(Component)); } } UAblSetShaderParameterTaskScratchPad* ScratchPad = Cast<UAblSetShaderParameterTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); ScratchPad->BlendIn = m_BlendIn; ScratchPad->BlendIn.Reset(); ScratchPad->BlendOut = m_BlendOut; ScratchPad->BlendOut.Reset(); UAblSetParameterValue* CachedValue = nullptr; for (TWeakObjectPtr<UPrimitiveComponent>& PrimitiveComponent : PrimitiveComponents) { if (PrimitiveComponent.IsValid()) { for (int32 i = 0; i < PrimitiveComponent->GetNumMaterials(); ++i) { UMaterialInterface* MaterialInterface = PrimitiveComponent->GetMaterial(i); UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface); // If our material currently isn't dynamic, but we have the parameter we're looking for - instantiate a dynamic version. if (!DynamicMaterial && CheckMaterialHasParameter(MaterialInterface)) { DynamicMaterial = PrimitiveComponent->CreateDynamicMaterialInstance(i, MaterialInterface); } if (DynamicMaterial) { CachedValue = CacheShaderValue(ScratchPad, DynamicMaterial); if (CachedValue) { ScratchPad->DynamicMaterials.Add(DynamicMaterial); ScratchPad->PreviousValues.Add(CachedValue); if (ScratchPad->BlendIn.IsComplete()) { // If there isn't any blend. Just set it here since we won't be ticking. InternalSetShaderValue(DynamicMaterial, m_Value, CachedValue, ScratchPad->BlendIn.GetAlpha()); } } } } } } }
void UAblSetShaderParameterTask::OnTaskEnd(const TWeakObjectPtr<const UAblAbilityContext>& Context, const EAblAbilityTaskResult Result) const { Super::OnTaskEnd(Context, Result); if (m_RestoreValueOnEnd) { UAblSetShaderParameterTaskScratchPad* ScratchPad = Cast<UAblSetShaderParameterTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); verify(ScratchPad->DynamicMaterials.Num() == ScratchPad->PreviousValues.Num()); for (int32 i = 0; i < ScratchPad->DynamicMaterials.Num(); ++i) { InternalSetShaderValue(ScratchPad->DynamicMaterials[i].Get(), ScratchPad->PreviousValues[i].Get(), m_Value, 1.0); } } }
void UAblSetShaderParameterTask::OnTaskTick(const TWeakObjectPtr<const UAblAbilityContext>& Context, float deltaTime) const { Super::OnTaskTick(Context, deltaTime); UAblSetShaderParameterTaskScratchPad* ScratchPad = Cast<UAblSetShaderParameterTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); if (!ScratchPad->BlendIn.IsComplete()) { ScratchPad->BlendIn.Update(deltaTime); verify(ScratchPad->DynamicMaterials.Num() == ScratchPad->PreviousValues.Num()); for (int32 i = 0; i < ScratchPad->DynamicMaterials.Num(); ++i) { InternalSetShaderValue(ScratchPad->DynamicMaterials[i].Get(), m_Value, ScratchPad->PreviousValues[i].Get(), ScratchPad->BlendIn.GetBlendedValue()); } } else if (m_RestoreValueOnEnd && !ScratchPad->BlendOut.IsComplete()) { // If we're within range to start blending out, go ahead and start that process. if (GetEndTime() - Context->GetCurrentTime() < ScratchPad->BlendOut.GetBlendTime()) { ScratchPad->BlendOut.Update(deltaTime); verify(ScratchPad->DynamicMaterials.Num() == ScratchPad->PreviousValues.Num()); for (int32 i = 0; i < ScratchPad->DynamicMaterials.Num(); ++i) { InternalSetShaderValue(ScratchPad->DynamicMaterials[i].Get(), ScratchPad->PreviousValues[i].Get(), m_Value, ScratchPad->BlendOut.GetBlendedValue()); } } } }
void UAblSetCollisionChannelResponseTask::OnTaskStart(const TWeakObjectPtr<const UAblAbilityContext>& Context) const { Super::OnTaskStart(Context); UAblSetCollisionChannelResponseTaskScratchPad* ScratchPad = nullptr; if (m_RestoreOnEnd) { ScratchPad = Cast<UAblSetCollisionChannelResponseTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); } // We need to convert our Actors to primitive components. TArray<TWeakObjectPtr<AActor>> TargetArray; GetActorsForTask(Context, TargetArray); TArray<TWeakObjectPtr<UPrimitiveComponent>> PrimitiveComponents; for (TWeakObjectPtr<AActor>& Target : TargetArray) { if (UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(Target->GetRootComponent())) { PrimitiveComponents.AddUnique(PrimitiveComponent); } } for (TWeakObjectPtr<UPrimitiveComponent>& Component : PrimitiveComponents) { if (Component.IsValid()) { if (m_RestoreOnEnd) { if (m_SetAllChannelsToResponse) { const FCollisionResponseContainer& Container = Component->GetCollisionResponseToChannels(); for (ECollisionChannel Channel : TEnumRange<ECollisionChannel>()) { ScratchPad->PreviousCollisionValues.Add(FCollisionLayerResponseEntry(Component.Get(), Channel, Container.GetResponse(Channel))); } } else { ScratchPad->PreviousCollisionValues.Add(FCollisionLayerResponseEntry(Component.Get(), m_Channel.GetValue(), Component->GetCollisionResponseToChannel(m_Channel))); } } if (m_SetAllChannelsToResponse) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Setting All Collision Responses on Actor %s to %s."), *Component->GetOwner()->GetName(), *FAbleLogHelper::GetCollisionResponseEnumAsString(m_Response.GetValue()))); } #endif Component->SetCollisionResponseToAllChannels(m_Response.GetValue()); } else { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Setting Collision Channel %s Response on Actor %s to %s."), *FAbleLogHelper::GetCollisionChannelEnumAsString(m_Channel.GetValue()), *Component->GetOwner()->GetName(), *FAbleLogHelper::GetCollisionResponseEnumAsString(m_Response.GetValue()))); } #endif Component->SetCollisionResponseToChannel(m_Channel.GetValue(), m_Response.GetValue()); } } } }
void UAblSetCollisionChannelResponseTask::OnTaskEnd(const TWeakObjectPtr<const UAblAbilityContext>& Context, const EAblAbilityTaskResult result) const { Super::OnTaskEnd(Context, result); if (m_RestoreOnEnd) { UAblSetCollisionChannelResponseTaskScratchPad* ScratchPad = Cast<UAblSetCollisionChannelResponseTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); for (const FCollisionLayerResponseEntry& Entry : ScratchPad->PreviousCollisionValues) { if (Entry.Primitive.IsValid()) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Setting Collision Channel %s Response on Actor %s to %s."), *FAbleLogHelper::GetCollisionChannelEnumAsString(Entry.Channel), *Entry.Primitive->GetOwner()->GetName(), *FAbleLogHelper::GetCollisionResponseEnumAsString(Entry.Response))); } #endif Entry.Primitive->SetCollisionResponseToChannel(Entry.Channel, Entry.Response); } } } }
void UAblRayCastQueryTask::OnTaskStart(const TWeakObjectPtr<const UAblAbilityContext>& Context) const { Super::OnTaskStart(Context); AActor* SourceActor = m_QueryLocation.GetSourceActor(*Context.Get()); check(SourceActor); UWorld* World = SourceActor->GetWorld(); FTransform QueryTransform; m_QueryLocation.GetTransform(*Context.Get(), QueryTransform); const FVector RayStart = QueryTransform.GetLocation(); const FVector RayEnd = RayStart + QueryTransform.GetRotation().GetForwardVector() * m_Length; if (m_UseAsyncQuery && UAbleSettings::IsAsyncEnabled()) { UAblRayCastQueryTaskScratchPad* ScratchPad = Cast<UAblRayCastQueryTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); if (m_OnlyReturnBlockingHit) { ScratchPad->AsyncHandle = World->AsyncLineTraceByChannel(EAsyncTraceType::Single, RayStart, RayEnd, m_CollisionChannel); } else { ScratchPad->AsyncHandle = World->AsyncLineTraceByChannel(EAsyncTraceType::Multi, RayStart, RayEnd, m_CollisionChannel); } } else { TArray<FHitResult> HitResults; FHitResult TraceResult; if (m_OnlyReturnBlockingHit) { if (World->LineTraceSingleByChannel(TraceResult, RayStart, RayEnd, m_CollisionChannel)) { HitResults.Add(TraceResult); } } else { World->LineTraceMultiByChannel(HitResults, RayStart, RayEnd, m_CollisionChannel); } #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Raycast found %d results."), HitResults.Num())); } #endif if (HitResults.Num()) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { // Quick distance print help to see if we hit ourselves. float DistanceToBlocker = HitResults[HitResults.Num() - 1].Distance; PrintVerbose(FString::Printf(TEXT("Raycast blocking hit distance: %4.2f."), DistanceToBlocker)); } #endif if (m_CopyResultsToContext) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Copying %d results into Context."), HitResults.Num())); } #endif CopyResultsToContext(HitResults, Context); } if (m_FireEvent) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Firing Raycast Event %s with %d results."), *m_Name.ToString(), HitResults.Num())); } #endif Context->GetAbility()->OnRaycastEvent(Context.Get(), m_Name, HitResults); } } } #if !UE_BUILD_SHIPPING if (FAblAbilityDebug::ShouldDrawQueries()) { FAblAbilityDebug::DrawRaycastQuery(World, QueryTransform, m_Length); } #endif }