FadeObjects - рдХреИрдорд░реЗ рдФрд░ рдЪрд░рд┐рддреНрд░ рдХреЗ рдмреАрдЪ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЫрд┐рдкрд╛рдПрдВ

рдЫрд╡рд┐

рдПрдХ рдмрд╛рд░, рдХреИрдорд░реЗ рдФрд░ рдЪрд░рд┐рддреНрд░ рдХреЗ рдмреАрдЪ рдпрд╛ рдЖрд░рдЯреАрдПрд╕ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдХрдИ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рдмреАрдЪ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдореИрдВ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЗрдВрдЬрди рдореЗрдВ рдЕрдкрдиреА рдпрд╛рддреНрд░рд╛ рд╢реБрд░реВ рдХреАред рдпрд╣ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓, рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐, C ++ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЬреАрдердм рдкрд░ рд╕рдВрд▓рдЧреНрди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдмреНрд▓реВрдкреНрд░рд┐рдВрдЯ рдкрд░ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реЛрдЧрд╛, рджреЛрдиреЛрдВ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕рдорд╛рди рд╣реИред

рд╡реАрдбрд┐рдпреЛ рдЙрджрд╛рд╣рд░рдг


рдФрд░ рдЗрд╕рд▓рд┐рдП, рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред рд╣рдо рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдХрдИ рдЫреЛрдЯреЗ рд▓реЛрдЧреЛрдВ рдореЗрдВ рдмрд╛рдБрдЯрддреЗ рд╣реИрдВ:

  1. рдХреИрдорд░реЗ рдФрд░ рдЪрд░рд┐рддреНрд░ рдХреЗ рдмреАрдЪ рдХреА рд╡рд╕реНрддреБрдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
  2. рдЗрди рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдореЗрдВ рдмрджрд▓реЗрдВред
  3. рд╕рд╛рдордЧреНрд░реА рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрджрд▓реЗрдВ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рдерд╛ рдпрджрд┐ рд╡рд╕реНрддреБ рд╣рдорд╛рд░реЗ рдЪрд░рд┐рддреНрд░ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдореЗрдВ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рддреА рд╣реИред

рд╣рдореЗрдВ 2 рдЯрд╛рдЗрдорд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдПрдХ рдХреЛ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рджреВрд╕рд░рд╛ рд╕реНрд╡рдпрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд╕реЗ рдереЛрдбрд╝рд╛ рдкрд╛рд░рджрд░реНрд╢реА рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реВрдВред рдЖрдк рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрдкрдиреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдХрд┐рд╕реА рднреА рд╕рд╛рдордЧреНрд░реА рд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

SFadeObjectsComponent.h

FTimerHandle timerHandle_ObjectComputeTimer; FTimerHandle timerHandle_AddObjectsTimer; 

рдЬреИрд╕реЗ рд╣реА рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рд░рдгреА рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рдЖрдЧреЗ рдХреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдХреБрдЫ рдЧреБрдгреЛрдВ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдмрджрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╕рд╛рдордЧреНрд░реА рдереА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рдзреАрд░реЗ-рдзреАрд░реЗ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдВрдЧреЗ:
 USTRUCT() struct FFadeObjStruct { GENERATED_USTRUCT_BODY() UPROPERTY() UPrimitiveComponent* primitiveComp; UPROPERTY() TArray<UMaterialInterface*> baseMatInterface; UPROPERTY() TArray<UMaterialInstanceDynamic*> fadeMID; UPROPERTY() float fadeCurrent; UPROPERTY() bool bToHide; void NewElement(UPrimitiveComponent* newComponent, TArray<UMaterialInterface*> newBaseMat, <UMaterialInstanceDynamic*> newMID, float currentFade, bool bHide) { primitiveComp = newComponent; baseMatInterface = newBaseMat; fadeMID = newMID; fadeCurrent = currentFade; bToHide = bHide; } void SetHideOnly(bool hide) { bToHide = hide; } void SetFadeAndHide(float newFade, bool newHide) { fadeCurrent = newFade; bToHide = newHide; } //For Destroy void Destroy() { primitiveComp = nullptr; } //Constructor FFadeObjStruct() { primitiveComp = nullptr; fadeCurrent = 0; bToHide = true; } }; 


рд╣рдореЗрдВ рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЗ рд▓рдЪреАрд▓реЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдмреНрд▓реВрдкреНрд░рд┐рдВрдЯ рд╕реЗ рдЙрдкрд▓рдмреНрдз рдХреБрдЫ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рднреА рдЪрд╛рд╣рд┐рдПред рдЬреИрд╕реЗ рдХрд┐ рд╡рд╕реНрддреБрдУрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрдХрд░рд╛рд╡ рдХрд╛ рдкреНрд░рдХрд╛рд░, рдХреИрдкреНрд╕реВрд▓ рдХрд╛ рдЖрдХрд╛рд░ (рдмреАрдо рдЦреБрдж) рдХреИрдорд░реЗ рдХреЗ рдЪрд░рд┐рддреНрд░ рд╕реЗ, рдЖрдХрд╛рд░ рдЬрд┐рддрдирд╛ рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛, рдЪрд░рд┐рддреНрд░ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреА рдЕрдзрд┐рдХ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 // Check trace block by this UPROPERTY(EditAnywhere, Category = "Fade Objects") TArray<TEnumAsByte<ECollisionChannel>> objectTypes; // Trace object size UPROPERTY(EditAnywhere, Category = "Fade Objects") float capsuleHalfHeight; // Trace object size UPROPERTY(EditAnywhere, Category = "Fade Objects") float capsuleRadius; 

рд╡рд╣ рджреВрд░реА рдЬрд┐рд╕ рдкрд░ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЫрд┐рдкрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 UPROPERTY(EditAnywhere, Category = "Fade Objects") float workDistance; 

рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЪрд░рд┐рддреНрд░ рд╡рд░реНрдЧ рдЦреБрдж рдпрд╛ рджреГрд╢реНрдп рдореЗрдВ рдЕрдиреНрдп рдЕрднрд┐рдиреЗрддрд╛рдУрдВред

 UPROPERTY(EditAnywhere, Category = "Fade Objects") UClass* playerClass; 

рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕рднреА рдЪрд░ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдЖрдк рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЗрдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВред BeginPlay рдореЗрдВ, рд╣рдорд╛рд░реА рдЯрд╛рдЗрдорд░ рдЪрд▓рд╛рдПрдВред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдорд░ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк EventTick рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдпрджрд┐ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реАрдкреАрдпреВ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдорд╣рдВрдЧреА рд╣реИ, рддреЛ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрд╢рди рд╣реАред

SFadeObjectsComponent.cpp

 GetWorld()->GetTimerManager().SetTimer(timerHandle_AddObjectsTimer, this, &USFadeObjectsComponent::AddObjectsToHide, addObjectInterval, true); GetWorld()->GetTimerManager().SetTimer(timerHandle_ObjectComputeTimer, this, &USFadeObjectsComponent::FadeObjWorker, calcFadeInterval, true); 

рдХрд┐рд╕реА рд╕рд░рдгреА рдореЗрдВ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпред рдпрд╣рд╛рдБ рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рди рдХреЗрд╡рд▓ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рджреГрд╢реНрдп рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЗрд╕рдХреЗ рдШрдЯрдХреЛрдВ рдФрд░ рд╕реНрдХреАрд▓реЗрдЯрдореЗрд╢ рдХреЛ рднреА, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛред
 void USFadeObjectsComponent::AddObjectsToHide() { UGameplayStatics::GetAllActorsOfClass(this, playerClass, characterArray); for (AActor* currentActor : characterArray) { const FVector traceStart = GEngine->GetFirstLocalPlayerController(GetWorld())->PlayerCameraManager->GetCameraLocation(); const FVector traceEnd = currentActor->GetActorLocation(); const FRotator traceRot = currentActor->GetActorRotation(); FVector traceLentgh = traceStart - traceEnd; const FQuat acQuat = currentActor->GetActorQuat(); if (traceLentgh.Size() < workDistance) { FCollisionQueryParams traceParams(TEXT("FadeObjectsTrace"), true, GetOwner()); traceParams.AddIgnoredActors(actorsIgnore); traceParams.bTraceAsyncScene = true; traceParams.bReturnPhysicalMaterial = false; // Not tracing complex uses the rough collision instead making tiny objects easier to select. traceParams.bTraceComplex = false; TArray<FHitResult> hitArray; TArray<TEnumAsByte<EObjectTypeQuery>> traceObjectTypes; // Convert ECollisionChannel to ObjectType for (int i = 0; i < objectTypes.Num(); ++i) { traceObjectTypes.Add(UEngineTypes::ConvertToObjectType(objectTypes[i].GetValue())); } // Check distance between camera and player for new object to fade, and add this in array GetWorld()->SweepMultiByObjectType(hitArray, traceStart, traceEnd, acQuat, traceObjectTypes, FCollisionShape::MakeCapsule(capsuleRadius, capsuleHalfHeight), traceParams); for (int hA = 0; hA < hitArray.Num(); ++hA) { if (hitArray[hA].bBlockingHit && IsValid(hitArray[hA].GetComponent()) && !fadeObjectsHit.Contains(hitArray[hA].GetComponent())) { fadeObjectsHit.AddUnique(hitArray[hA].GetComponent()); } } } } // Make fade array after complete GetAllActorsOfClass loop for (int fO = 0; fO < fadeObjectsHit.Num(); ++fO) { // If not contains this component in fadeObjectsTemp if (!fadeObjectsTemp.Contains(fadeObjectsHit[fO])) { TArray<UMaterialInterface*> lBaseMaterials; TArray<UMaterialInstanceDynamic*> lMidMaterials; lBaseMaterials.Empty(); lMidMaterials.Empty(); fadeObjectsTemp.AddUnique(fadeObjectsHit[fO]); // For loop all materials ID in object for (int nM = 0; nM < fadeObjectsHit[fO]->GetNumMaterials(); ++nM) { lMidMaterials.Add(UMaterialInstanceDynamic::Create(fadeMaterial, fadeObjectsHit[fO])); lBaseMaterials.Add(fadeObjectsHit[fO]->GetMaterial(nM)); // Set new material on object fadeObjectsHit[fO]->SetMaterial(nM, lMidMaterials.Last()); } // Create new fade object in array of objects to fade FFadeObjStruct newObject; newObject.NewElement(fadeObjectsHit[fO], lBaseMaterials, lMidMaterials, immediatelyFade, true); // Add object to array fadeObjects.Add(newObject); // Set collision on Primitive Component fadeObjectsHit[fO]->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore); } } // Set hide to visible true if contains for (int fOT = 0; fOT < fadeObjectsTemp.Num(); ++fOT) { if (!fadeObjectsHit.Contains(fadeObjectsTemp[fOT])) { fadeObjects[fOT].SetHideOnly(false); } } // Clear array fadeObjectsHit.Empty(); } 


рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдореВрд▓ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓рддрд╛ рд╣реИред
 void USFadeObjectsComponent::FadeObjWorker() { if (fadeObjects.Num() > 0) { // For loop all fade objects for (int i = 0; i < fadeObjects.Num(); ++i) { // Index of iteration int fnID = i; float adaptiveFade; if (fnID == fadeObjects.Num()) { adaptiveFade = nearObjectFade; } else { adaptiveFade = farObjectFade; } // For loop fadeMID array for (int t = 0; t < fadeObjects[i].fadeMID.Num(); ++t) { float targetF; const float currentF = fadeObjects[i].fadeCurrent; if (fadeObjects[i].bToHide) { targetF = adaptiveFade; } else { targetF = 1.0f; } const float newFade = FMath::FInterpConstantTo(currentF, targetF, GetWorld()->GetDeltaSeconds(), fadeRate); fadeObjects[i].fadeMID[t]->SetScalarParameterValue("Fade", newFade); currentFade = newFade; fadeObjects[i].SetFadeAndHide(newFade, fadeObjects[i].bToHide); } // remove index in array if (currentFade == 1.0f) { for (int bmi = 0; bmi < fadeObjects[fnID].baseMatInterface.Num(); ++bmi) { fadeObjects[fnID].primitiveComp->SetMaterial(bmi, fadeObjects[fnID].baseMatInterface[bmi]); } fadeObjects[fnID].primitiveComp->SetCollisionResponseToChannel(ECC_Camera, ECR_Block); fadeObjects.RemoveAt(fnID); fadeObjectsTemp.RemoveAt(fnID); } } } } 


рдпрд╣рд╛рдВ рдХреБрдЫ рднреА рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдирд╣реАрдВ рд╣реИ, рдХреЛрдб рдХреЗ рдХреБрдЫ рдЯреБрдХрдбрд╝реЗ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдЗрддрдиреЗ рдкрд░ред рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдореИрдВ рдХреЗрд╡рд▓ рдЙрди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬрд┐рдирдХреЗ рд╕рд╛рде рдШрдЯрдХ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

 PrimaryComponentTick.bCanEverTick = false; bEnable = true; addObjectInterval = 0.1f; calcFadeInterval = 0.05f; fadeRate = 10.0f; capsuleHalfHeight = 88.0f; capsuleRadius = 34.0f; workDistance = 5000.0f; nearCameraRadius = 300.0f; nearObjectFade = 0.3; farObjectFade = 0.1; immediatelyFade = 0.5f; // Add first collision type objectTypes.Add(ECC_WorldStatic); 

рд╢рд╛рдпрдж рдХреЛрдИ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдпрд╛ рдХреЛрдИ рдЕрдкрдиреА рд░рд╛рдп рдХрдореЗрдВрдЯ рдореЗрдВ рдмрддрд╛рдПрдЧрд╛ред

рд╕реНрд░реЛрдд рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ

Source: https://habr.com/ru/post/hi425389/


All Articles