Creating a Point Light Component in Unreal Engine 5 with C++

Adding a point light component to an actor is fairly straight forward and can be pretty fun when we randomize the colors.

Unreal Engine 5 Quinn standing in the point light section of the GD Tactics gym
Quinn beneath the lights

Software Versions: Unreal Engine 5.5.1 | Rider 2024.3.2

Project Name: MyProject

Create a new actor class, I called mine MyPointClass. I added a forward reference at the top of file above the class declaration with class UPointLightComponent;. Then inside the class I added a couple of simple properties to build out the actor. I also added a couple functions to have fun with the demo that will radomized the color when called.

MyPointLight.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyPointLight.generated.h"

class UPointLightComponent;

UCLASS()
class MYPROJECT_API AMyPointLight : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyPointLight();
	
	UPROPERTY(EditAnywhere)
	USceneComponent* MyRoot;

	UPROPERTY(EditAnywhere)
	UPointLightComponent* MyPointLight;

	UPROPERTY()
	FTimerHandle TimerHandle;
	
	UFUNCTION()
	void ToggleTimer();

	void SetRandomColor();
};

First, inside the .cpp file you'll need to include the point light component with #include "Components/PointLightComponent.h". Then inside the actor's constructor I chose some popular point light values to set at random. The ToggleTimer function will be called from another actor on overlap to randomly set the point light's color every one to three seconds.

MyPointLight.cpp

#include "MyPointLight.h"
#include "Components/PointLightComponent.h"


// Sets default values
AMyPointLight::AMyPointLight()
{
	MyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("MyRoot"));
	RootComponent = MyRoot;

	MyPointLight = CreateDefaultSubobject<UPointLightComponent>(TEXT("MyPointLight"));
	MyPointLight->SetLightColor(FColor::MakeRandomColor());
	MyPointLight->SetIntensity(FMath::RandRange(5000.f, 10000.f));
	MyPointLight->SetUseTemperature(FMath::RandBool());
	MyPointLight->SetTemperature(FMath::RandRange(4000.f, 8000.f));
	MyPointLight->SetAttenuationRadius(FMath::RandRange(1000.f, 2000.f));
	MyPointLight->SetSourceRadius(FMath::RandRange(0.f, 100.f));
	MyPointLight->SetupAttachment(RootComponent);
}

void AMyPointLight::ToggleTimer()
{
	if (GetWorldTimerManager().IsTimerActive(TimerHandle))
	{
		GetWorldTimerManager().ClearTimer(TimerHandle);
	}
	else
	{
		GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyPointLight::SetRandomColor, FMath::RandRange(1.f, 3.f), true, 0.f);
	}
}

void AMyPointLight::SetRandomColor()
{
	MyPointLight->SetLightColor(FColor::MakeRandomColor());
}

Next, solely for the GD Tactics Gym, I created a overlap trigger that on overlap loops through a TArray of MyPointLights to start each point light's timer function.

MyPointLightToggleTrigger.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyPointLightToggleTrigger.generated.h"

class AMyPointLight;
class UBoxComponent;
class UTextRenderComponent;


UCLASS()
class MYPROJECT_API AMyPointLightToggleTrigger : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyPointLightToggleTrigger();

	UPROPERTY(EditAnywhere)
	USceneComponent* MyRoot;

	UPROPERTY(EditAnywhere)
	UStaticMeshComponent* MyStaticMesh;

	UPROPERTY(EditAnywhere)
	UBoxComponent* MyBoxComponent;

	UPROPERTY(EditAnywhere)
	UTextRenderComponent* MyTextRenderComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<AMyPointLight*> MyPointLights;

	UFUNCTION()
	void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
};

MyPointLightToggleTrigger.cpp

#include "MyPointLightToggleTrigger.h"
#include "MyPointLight.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"


// Sets default values
AMyPointLightToggleTrigger::AMyPointLightToggleTrigger()
{
	MyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("MyRoot"));
	MyRoot->bVisualizeComponent = true;
	RootComponent = MyRoot;

	MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh"));
	MyStaticMesh->SetupAttachment(RootComponent);

	MyTextRenderComponent = CreateDefaultSubobject<UTextRenderComponent>(TEXT("MyTextRenderComponent"));
	MyTextRenderComponent->SetupAttachment(RootComponent);

	MyBoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("MyBoxComponent"));
	MyBoxComponent->SetupAttachment(RootComponent);

	MyBoxComponent->OnComponentBeginOverlap.AddDynamic(this, &AMyPointLightToggleTrigger::OnBeginOverlap);
}

void AMyPointLightToggleTrigger::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor != nullptr && OtherActor != this)
	{
		for (AMyPointLight* MyPointLight : MyPointLights)
		{
			MyPointLight->ToggleTimer();
		}
	}
}

Finally, after compiling the project we can directly drag the C++ actors into our level and enjoy the lights we have created.

Unreal Engine 5 Quinn standing in the point light section of the gym as the lights randomly change colors
Quinn at the disco

I had fun making this, hopefully this helps you in your game dev journey.

Loading...