
曾经,有必要编写一个模块以在摄像机和角色之间或RTS游戏的几个角色之间隐藏对象。 我想分享给那些开始使用虚幻引擎的人。 如果可以的话,本教程将使用C ++,但是在github上的附加项目中,Blueprint上有一个选项,两者的功能相同。
因此,我们走吧。 我们将任务分为几个小任务:
- 在摄像机和角色之间获取对象。
- 将这些对象的材质更改为所需的材质。
- 如果对象不干扰我们对角色的审查,则将材料更改回原样。
我们需要两个计时器,一个计时器用于将对象添加到数组中以与它们一起工作,第二个计时器用于更改对象本身,在这种情况下,我将材质从常规更改为稍微透明。 您可以使用任何适合您的材料代替该材料。
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; }
我们还需要Blueprint提供的一些设置来灵活地运行组件。 例如,用于识别对象的碰撞类型,从角色到摄像机的胶囊(光束本身)的大小,大小越大,将捕获角色周围的更多对象。
隐藏对象的距离。
UPROPERTY(EditAnywhere, Category = "Fade Objects") float workDistance;
当然,角色类本身或场景中的其他演员也是如此。
UPROPERTY(EditAnywhere, Category = "Fade Objects") UClass* playerClass;
我们不会分析所有使用的变量,您可以独立地熟悉来源。
让我们继续执行。 在BeginPlay中,运行我们的计时器。 当然,您可以使用EventTick来代替计时器,但最好不要这样做,如果CPU上有大量对象,操作本身会改变材质,那会更好。
SFadeObjectsComponent.cpp
GetWorld()->GetTimerManager().SetTimer(timerHandle_AddObjectsTimer, this, &USFadeObjectsComponent::AddObjectsToHide, addObjectInterval, true); GetWorld()->GetTimerManager().SetTimer(timerHandle_ObjectComputeTimer, this, &USFadeObjectsComponent::FadeObjWorker, calcFadeInterval, true);
将对象添加到数组的功能。 在这里,我想指出的是,它不仅添加了场景中的演员本人,而且还添加了其组件和SkeletalMesh(必要时)。 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;
处理对象的功能,可将材料从原始更改为所需,反之亦然。 void USFadeObjectsComponent::FadeObjWorker() { if (fadeObjects.Num() > 0) {
这里没有什么特别的要告诉的内容,有些代码等等带有注释。 开头的视频显示了结果。 我只想添加用于初始化组件的设置。
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;
也许有人会有用。 否则有人会在评论中说出他们的意见。
链接到源