Download

Multiple instances of class with realtime spotlights causing flicker

Hey everyone!

I am still somewhat new to UE4 but I am trying to get my feet wet by creating a class. The class is supposed to create a spotlight which follows the player while staying on a predefined path which can be edited by moving two spheres in the editor.

Just one by itself works really well! But as soon as I add a second one, one of the two lights flickers. It appears as though I can only have one realtime spotlight on screen at a time. What am I missing here? There’s no way this is right. I’m sure it’s my error, I just don’t know what it is.

Here is my class source.

//TranslatingSpotlight.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include “CoreMinimal.h”
#include “GameFramework/Actor.h”
#include “TranslatingSpotlight.generated.h”

class USpotLightComponent;

UCLASS()
class WALLACE_API ATranslatingSpotlight : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor’s properties
ATranslatingSpotlight();

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

private:
APlayerCameraManager* mCamera;

TArray<FVector> pathNodes;

public:
// Called every frame
virtual void Tick(float DeltaTime) override;

UPROPERTY(EditAnywhere)
    USceneComponent* root;
UPROPERTY(EditAnywhere)
    USceneComponent* pos1;
UPROPERTY(EditAnywhere)
    USceneComponent* pos2;

UPROPERTY(EditAnywhere)
    USpotLightComponent* mLight;

UPROPERTY(EditAnywhere, Category = "TranslateLight", meta = (ClampMin = "2", UIMin = "2"))
    int pathNodeCount = 3;

UPROPERTY(EditAnywhere, Category = "TranslateLight")
    float speed = 1.0f;

};

//TranslatingSpotlight.cpp
// Fill out your copyright notice in the Description page of Project Settings.

#include “TranslatingSpotlight.h”
#include “Kismet/GameplayStatics.h”
#include “Kismet/KismetMathLibrary.h”
#include “Engine/World.h”
#include “Camera/PlayerCameraManager.h”
#include “GameFramework/Actor.h”
#include “Components/SphereComponent.h”
#include “Components/StaticMeshComponent.h”
#include “Components/SpotLightComponent.h”

// Sets default values
ATranslatingSpotlight::ATranslatingSpotlight()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;

this->root = CreateDefaultSubobject<USphereComponent>(TEXT("root"));
this->root->Bounds = FBoxSphereBounds(FVector(0, 0, 0), FVector(500, 500, 500), 500);
this->RootComponent = this->root;

this->mLight = CreateDefaultSubobject<USpotLightComponent>(TEXT("Spotlight"));
this->mLight->SetIntensity(65000);
this->mLight->SetInnerConeAngle(60.0f);
this->mLight->SetOuterConeAngle(65.0f);
this->mLight->AttachTo(this->root);

this->pos1 = CreateDefaultSubobject<USphereComponent>(TEXT("Position 1 Marker"));
this->pos1->AttachTo(this->root);

this->pos2 = CreateDefaultSubobject<USphereComponent>(TEXT("Position 2 Marker"));
this->pos2->AttachTo(this->root);

}

// Called when the game starts or when spawned
void ATranslatingSpotlight::BeginPlay()
{
Super::BeginPlay();
this->mCamera = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

//Generate pathNodes
for (int i = 0; i < this->pathNodeCount; i++) {
    FVector mPos = this->pos2->GetComponentLocation() - this->pos1->GetComponentLocation();
    mPos = mPos / (this->pathNodeCount-1);
    mPos = mPos * i;
    mPos += this->root->GetComponentLocation();
    this->pathNodes.Emplace(mPos);
}

}

// Called every frame
void ATranslatingSpotlight::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);

if (this->mCamera) {

    int selectedPos = 0;
    for (int i = 0; i < this->pathNodes.Num(); i++) {
        if (FVector::Distance(this->pathNodes*, this->mCamera->GetCameraLocation()) < FVector::Distance(this->pathNodes[selectedPos], this->mCamera->GetCameraLocation()))
            selectedPos = i;
    }

    FVector newLoc = FMath::Lerp(this->mLight->GetComponentLocation(), this->pathNodes[selectedPos], DeltaTime*speed);
    this->mLight->SetWorldLocation(newLoc);

    //FRotator lookRot = UKismetMathLibrary::FindLookAtRotation(mLight->GetComponentLocation(), mCamera->GetCameraLocation());
    //mLight->SetWorldRotation(lookRot);
}

}

For reference, I have attempted simply creating two regular spotlights, and setting them to movable and that seems to work, but obviously that doesn’t help me too much.

I’m also open to any code suggestions as I am pretty new to C++.

Thanks!

Daniel Jackson