
Une fois, il a fallu écrire un module pour cacher des objets entre la caméra et le personnage, ou entre plusieurs personnages pour un jeu RTS. Je veux partager pour ceux qui ont commencé leur voyage dans Unreal Engine. Ce tutoriel, si vous pouvez l'appeler ainsi, utilisera C ++, mais dans le projet attaché sur github il y aura une option sur Blueprint, la fonctionnalité des deux est identique.
Et donc, allons-y. Nous divisons notre tâche en plusieurs petites:
- Obtenez des objets entre la caméra et le personnage.
- Changez le matériau de ces objets en celui souhaité.
- Remettez le matériau à ce qu'il était si l'objet n'interfère pas avec la révision de notre personnage.
Nous avons besoin de 2 minuteries, une pour ajouter des objets au tableau pour travailler avec eux, et la seconde pour changer l'objet lui-même, dans ce cas, je change le matériau de normal à légèrement transparent. Vous pouvez remplacer ce matériel par n'importe quel matériel qui vous convient.
SFadeObjectsComponent.h
FTimerHandle timerHandle_ObjectComputeTimer; FTimerHandle timerHandle_AddObjectsTimer;
Dès que l'objet est dans le tableau, pour poursuivre les travaux, nous devons nous souvenir de certaines de ses propriétés, par exemple, quel matériau il avait avant de le changer, car nous devons le changer en arrière. De plus, dans notre cas, nous masquons et, si nécessaire, nous retournons progressivement l'état initial de l'objet, nous devons donc nous souvenir de son état actuel.
Pour ce faire, nous allons créer une structure: 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; }
Nous avons également besoin de certains paramètres disponibles auprès de Blueprint pour le fonctionnement flexible de notre composant. Tels que le type de collision pour identifier les objets, la taille de la capsule (le faisceau lui-même) du personnage à la caméra, plus la taille est grande, plus les objets autour du personnage seront capturés.
La distance à laquelle les objets seront cachés.
UPROPERTY(EditAnywhere, Category = "Fade Objects") float workDistance;
Et bien sûr, le personnage lui-même ou d'autres acteurs de la scène.
UPROPERTY(EditAnywhere, Category = "Fade Objects") UClass* playerClass;
Nous n'analyserons pas toutes les variables utilisées, vous pouvez vous familiariser indépendamment avec les sources.
Passons à la mise en œuvre. Dans BeginPlay, exécutez nos minuteries. Au lieu de minuteries, vous pouvez bien sûr utiliser EventTick, mais il vaut mieux ne pas le faire, l'opération elle-même pour changer de matériau si un grand nombre d'objets est assez cher pour le CPU.
SFadeObjectsComponent.cpp
GetWorld()->GetTimerManager().SetTimer(timerHandle_AddObjectsTimer, this, &USFadeObjectsComponent::AddObjectsToHide, addObjectInterval, true); GetWorld()->GetTimerManager().SetTimer(timerHandle_ObjectComputeTimer, this, &USFadeObjectsComponent::FadeObjWorker, calcFadeInterval, true);
Fonction d'ajout d'un objet à un tableau. Ici, je voudrais noter qu'il ajoute non seulement l'acteur lui-même dans la scène, mais aussi ses composants et SkeletalMesh, si nécessaire. 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;
Une fonction pour travailler avec des objets qui change le matériau de l'original au nécessaire et vice versa. void USFadeObjectsComponent::FadeObjWorker() { if (fadeObjects.Num() > 0) {
Il n'y a rien de spécial à dire ici, quelques morceaux de code et ainsi de suite avec des commentaires. La vidéo au début montre le résultat. Je souhaite ajouter uniquement les paramètres avec lesquels le composant est initialisé.
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;
Peut-être que quelqu'un sera utile. Ou quelqu'un dira son avis dans les commentaires.
Lien vers la source