Hello, i’m not going to go preview this so i’ll just throw this whole thing here. This is fast build of Blueprint version.
You need to create two float curves. Leave them in game root folder. There is a list of assets in DayNightMPSky.cpp file so make sure you have those assets in right place or just change them in the code.
I didn’t test this much so there’s probably some bugs, but all features should work the same way as in Blueprint version.
This is an Actor Class so select Actor when you create a new class.
Tested in
4.25
4.26
4.27
5.00 Early Access 1
5.00 Early Access 2
5.00 Preview 2 (Nightsky doesn't fade away during day)
DayNightMPSky.h
// Level Paradox @levelparadox.com - Day and Night Multiplayer Tutorial
#pragma once
#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "Components/LightComponent.h"
#include "Components/SkyLightComponent.h"
#include "Components/DirectionalLightComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/ExponentialHeightFogComponent.h"
#include "Components/SkyAtmosphereComponent.h"
#include "Components/TimelineComponent.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Materials/MaterialInstanceConstant.h"
#include "UObject/ConstructorHelpers.h"
#include "Net/UnrealNetwork.h"
#include "Kismet/KismetSystemLibrary.h"
#include "SunPosition.h"
#include "TimerManager.h"
#include "DayNightCycle_ST_Rules.h"
#include "GameFramework/Actor.h"
class UStaticMeshComponent;
class UExponentialHeightFogComponent;
class UDirectionalLightComponent;
class USkyAtmosphereComponent;
class USkyLightComponent;
class USceneComponent;
class UTimelineComponent;
class UMaterialInstanceDynamic;
class UMaterialInstanceConstant;
#include "DayNightMPSky.generated.h"
//todo: add parameter when day or night ends
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FIsNight);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FIsDay);
UCLASS()
class ADayNightMPSky : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ADayNightMPSky();
//For timeline
float class_DeltaTime;
/**
Components
*/
UPROPERTY(BlueprintReadWrite, NonTransactional, meta = (Category = "Default", OverrideNativeName = "Scene"))
USceneComponent* Scene;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Category = "Default", OverrideNativeName = "SkyLight"))
USkyLightComponent* SkyLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Category = "Default", OverrideNativeName = "DirectionalLight"))
UDirectionalLightComponent* DirectionalLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Category = "Default", OverrideNativeName = "SkyAtmosphere"))
USkyAtmosphereComponent* SkyAtmosphere;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Category = "Default", OverrideNativeName = "MoonLight"))
UDirectionalLightComponent* MoonLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Category = "Default", OverrideNativeName = "ExponentialHeightFog"))
UExponentialHeightFogComponent* ExponentialHeightFog;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (AllowPrivateAccess = "true", Category = "Default", OverrideNativeName = "CompassMesh"))
UStaticMeshComponent* CompassMesh;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (AllowPrivateAccess = "true", Category = "Default", OverrideNativeName = "SkySphereMesh"))
UStaticMeshComponent* SkySphereMesh;
/**
Functions
*/
UFUNCTION(BlueprintCallable)
void UpdateSky();
UFUNCTION(BlueprintCallable)
void UpdateSun();
UFUNCTION(BlueprintCallable)
void GetHMSFromSolarTime(float SolarTime_loc, int32& Hour, int32& Minute, int32& Second);
UFUNCTION(BlueprintCallable)
void FromDateTime(FDateTime DateTime);
UFUNCTION(BlueprintPure)
void IsDST(bool DSTEnable, int32 DSTStartMonth_loc, int32 DSTStartDay_loc, int32 DSTEndMonth_loc, int32 DSTEndDa_loc, int32 DSTSwitchHour_loc, bool& isDST);
UFUNCTION(BlueprintCallable)
void MoveMoon();
//timeline
UFUNCTION(BlueprintCallable)
void StarsOnHelper(float Value);
//timeline
UFUNCTION(BlueprintCallable)
void StarsOffHelper(float Value);
UFUNCTION(BlueprintCallable)
void StarsOnTickTimeline();
UFUNCTION(BlueprintCallable)
void StarsOffTickTimeline();
UFUNCTION(BlueprintCallable)
void enableskyspam();
/**
Event functions
*/
void UpdateRealTime();
void SetLocationRealTime();
void SetMoon();
void SunIsDown();
void StarsOn();
void StarsOff();
/**
Variables
*/
//Location
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float Latitude;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float Longitude;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float TimeZone;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float NorthOffset;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float Elevation;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float CorrectedElevation;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Location"))
float Azimuth;
//Date
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 Year;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 Month;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 Day;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
bool UseDaylightSavingsTime;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 DSTStartMonth;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 DSTSTartDay;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 DSTEndMonth;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 DSTEndDay;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Date"))
int32 DSTSwitchHours;
//Time
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Time"))
float SolarTime;
//Event Tick
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Event Tick"))
float HashVal;
//Default
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
UMaterialInstanceDynamic* SkyMaterial;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
bool StarsAreOn;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
float MaxStarsBrightness;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
int32 BeginDay;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
bool IsNight_B;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
bool UpdateSkySpamPrevention;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
FTimespan Sunset;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
FTimespan Sunrise;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
FDateTime GameTimeNow;
UPROPERTY(Replicated, BlueprintReadWrite)
FDayNightCyclerRules_cpp DN_Rules;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (Category = "Default"))
FUTCTimeDifference_cpp UTCTimeDifference;
//Other
UPROPERTY(BlueprintAssignable, Category = "Event Dispatchers")
FIsNight IsNight;
UPROPERTY(BlueprintAssignable, Category = "Event Dispatchers")
FIsDay IsDay;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
//Replication
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const;
private:
UMaterialInterface* SkyMatFound;
bool tickfirst_timer_on;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void OnConstruction(const FTransform& Transform);
FTimerHandle tickfirst_timer;
FTimeline StarsOnTimeline;
FTimeline StarsOffTimeline;
FTimerHandle StarsOnTimerHandle;
FTimerHandle StarsOffTimerHandle;
};
DayNightMPSky.cpp
// Level Paradox @levelparadox.com - Day and Night Multiplayer Tutorial
/*
debug:
UKismetSystemLibrary::PrintString(GetWorld(), GameTimeNow.ToString());
List of assets:
CurveFloat'/Game/StarsOnCurve.StarsOnCurve'
CurveFloat'/Game/StarsOffCurve.StarsOffCurve'
StaticMesh'/SunPosition/Editor/SM_Compass.SM_Compass'
StaticMesh'/Engine/EngineSky/SM_SkySphere.SM_SkySphere'
MaterialInstanceConstant'/Game/M_SkyMaterial_Inst.M_SkyMaterial_Inst'
/Game/M_SkyMaterial.M_SkyMaterial
*/
#include "DayNightMPSky.h"
// Sets default values
ADayNightMPSky::ADayNightMPSky()
{
// 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;
UseDaylightSavingsTime = true;
UpdateSkySpamPrevention = true;
Latitude = 45.0f;
Longitude = -73.0f;
TimeZone = -5.0f;
NorthOffset = 0.0f;
Elevation = 0.0f;
CorrectedElevation = 0.0f;
Azimuth = 0.0f;
SolarTime = 22.0f;
Year = 2019;
Month = 9;
Day = 21;
DSTStartMonth = 3;
DSTSTartDay = 10;
DSTEndMonth = 11;
DSTEndDay = 3;
DSTSwitchHours = 2;
MaxStarsBrightness = 1.5f;
BeginDay = 0;
tickfirst_timer_on = false;
//Enable replication for this class
bReplicates = true;
//Timelines
const ConstructorHelpers::FObjectFinder<UCurveFloat> Curve_StarsOn(TEXT("CurveFloat'/Game/StarsOnCurve.StarsOnCurve'"));
StarsOnTimeline = FTimeline{};
FOnTimelineFloat progressFunction_one{};
progressFunction_one.BindUFunction(this, "StarsOnHelper");
StarsOnTimeline.AddInterpFloat(Curve_StarsOn.Object, progressFunction_one, FName{ TEXT("EFFECTFADE") });
const ConstructorHelpers::FObjectFinder<UCurveFloat> Curve_StarsOff(TEXT("CurveFloat'/Game/StarsOffCurve.StarsOffCurve'"));
StarsOffTimeline = FTimeline{};
FOnTimelineFloat progressFunction_two{};
progressFunction_two.BindUFunction(this, "StarsOffHelper");
StarsOffTimeline.AddInterpFloat(Curve_StarsOff.Object, progressFunction_two, FName{ TEXT("EFFECTFADE") });
Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
CompassMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CompassMesh"));
SkyLight = CreateDefaultSubobject<USkyLightComponent>(TEXT("SkyLight"));
DirectionalLight = CreateDefaultSubobject<UDirectionalLightComponent>(TEXT("DirectionalLight"));
SkyAtmosphere = CreateDefaultSubobject<USkyAtmosphereComponent>(TEXT("SkyAtmosphere"));
MoonLight = CreateDefaultSubobject<UDirectionalLightComponent>(TEXT("MoonLight"));
ExponentialHeightFog = CreateDefaultSubobject<UExponentialHeightFogComponent>(TEXT("ExponentialHeightFog"));
SkySphereMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SkySphereMesh"));
RootComponent = Scene;
Scene->CreationMethod = EComponentCreationMethod::Native;
Scene->Mobility = EComponentMobility::Type::Static;
//Height fog
FLinearColor albedofogcolor = FLinearColor(0.603827, 0.603827, 0.603827, 1.0f);
ExponentialHeightFog->FogDensity = 0.05f;
ExponentialHeightFog->SetVolumetricFog(true);
ExponentialHeightFog->VolumetricFogScatteringDistribution = 0.9f;
ExponentialHeightFog->VolumetricFogAlbedo = albedofogcolor.ToFColor(false);
ExponentialHeightFog->VolumetricFogExtinctionScale = 15.0f;
ExponentialHeightFog->SetHiddenInGame(true);
//Skylight
SkyLight->SetMobility(EComponentMobility::Movable);
SkyLight->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
SkyLight->SourceType = ESkyLightSourceType::SLS_CapturedScene;
SkyLight->SamplesPerPixel = 2;
//DirectionalLight
DirectionalLight->SetMobility(EComponentMobility::Movable);
DirectionalLight->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
//DirectionalLight->Intensity = 10;
DirectionalLight->ULightComponent::SetIntensity(10.000000);
//Comment this one in UE5 Preview2
DirectionalLight->bUsedAsAtmosphereSunLight = true;
//Uncomment this one in UE5 Preview2
//DirectionalLight->bAtmosphereSunLight = true;
DirectionalLight->LightSourceAngle = 0.500000f;
DirectionalLight->DynamicShadowCascades = 5;
DirectionalLight->CascadeDistributionExponent = 1.400000f;
//SkyAtmosphere
SkyAtmosphere->SetMobility(EComponentMobility::Movable);
SkyAtmosphere->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
//MoonLight
MoonLight->SetMobility(EComponentMobility::Movable);
MoonLight->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
MoonLight->DynamicShadowCascades = 5;
MoonLight->CascadeDistributionExponent = 1.400000f;
MoonLight->LightSourceAngle = 0.500000f;
//Comment this one in UE5 Preview2
MoonLight->bUsedAsAtmosphereSunLight = true;
//Uncomment this one in UE5 Preview2
//MoonLight->bAtmosphereSunLight = true;
MoonLight->Temperature = 4000.000000f;
MoonLight->bUseTemperature = true;
MoonLight->Intensity = 0.000000f;
//CompassMesh
CompassMesh->SetMobility(EComponentMobility::Movable);
CompassMesh->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
CompassMesh->OverrideMaterials = TArray<UMaterialInterface*>();
CompassMesh->OverrideMaterials.Reserve(1);
CompassMesh->OverrideMaterials.Add(nullptr);
CompassMesh->bVisibleInReflectionCaptures = false;
CompassMesh->bVisibleInRayTracing = false;
CompassMesh->CastShadow = false;
CompassMesh->SetCollisionProfileName(FName(TEXT("NoCollision")));
FRotator CompassMeshRotation = FRotator(0.000000, 90.000000, 0.000000);
CompassMesh->SetRelativeRotation(CompassMeshRotation.Quaternion());
CompassMesh->SetHiddenInGame(true);
CompassMesh->bIsEditorOnly = true;
static ConstructorHelpers::FObjectFinder<UStaticMesh> CMPMesh(TEXT("StaticMesh'/SunPosition/Editor/SM_Compass.SM_Compass'"));
if (CMPMesh.Succeeded())
{
CompassMesh->SetStaticMesh(CMPMesh.Object);
}
//SkySphereMesh
SkySphereMesh->CreationMethod = EComponentCreationMethod::Native;
SkySphereMesh->AttachToComponent(Scene, FAttachmentTransformRules::KeepRelativeTransform);
SkySphereMesh->SetMobility(EComponentMobility::Static);
SkySphereMesh->OverrideMaterials = TArray<UMaterialInterface*>();
SkySphereMesh->OverrideMaterials.Add(nullptr);
SkySphereMesh->SetCollisionProfileName(FName(TEXT("NoCollision")));
SkySphereMesh->SetRelativeScale3D(FVector(400.000000, 400.000000, 400.000000));
SkySphereMesh->bVisibleInRayTracing = false;
SkySphereMesh->bReceivesDecals = false;
SkySphereMesh->CastShadow = false;
SkySphereMesh->bAffectDynamicIndirectLighting = false;
SkySphereMesh->bCastDynamicShadow = false;
SkySphereMesh->bCastStaticShadow = false;
SkySphereMesh->BodyInstance.bAutoWeld = false;
SkySphereMesh->SetGenerateOverlapEvents(false);
static ConstructorHelpers::FObjectFinder<UStaticMesh> MSHSkySphere(TEXT("StaticMesh'/Engine/EngineSky/SM_SkySphere.SM_SkySphere'"));
if (MSHSkySphere.Succeeded())
{
SkySphereMesh->SetStaticMesh(MSHSkySphere.Object);
}
static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> X_SphereMaterialInstance(TEXT("MaterialInstanceConstant'/Game/M_SkyMaterial_Inst.M_SkyMaterial_Inst'"));
if (X_SphereMaterialInstance.Succeeded())
{
SkySphereMesh->SetMaterial(0, X_SphereMaterialInstance.Object);
}
//find skymaterial
SkyMatFound = nullptr;
static ConstructorHelpers::FObjectFinder<UMaterial> SkyMatFind(TEXT("/Game/M_SkyMaterial.M_SkyMaterial"));
if (SkyMatFind.Succeeded())
{
SkyMatFound = SkyMatFind.Object;
}
}
//Replication
void ADayNightMPSky::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ADayNightMPSky, DN_Rules);
}
// Called when the game starts or when spawned
void ADayNightMPSky::BeginPlay()
{
Super::BeginPlay();
FDayNightCyclerRules_cpp Make;
FDateTime gw_sst = FDateTime(2009, 1, 20, 18, 0, 0, 0);
FTimespan rwtigt = FTimespan(0, 1, 0);
Make.RealWorld_StaticStartTime = FDateTime::UtcNow();
Make.GameWorld_StaticStartTime = gw_sst;
Make.RealWorldTimeInGameTime = rwtigt;
Make.Latitude = 45.0f;
Make.Longitude = -73.0f;
Make.TimeZone = -5.0f;
Make.NorthOffset = 0.0f;
Make.Moon = true;
Make.MoonLightStrength = 0.1f;
Make.MoonDistance = 0.0f;
Make.MoonSize = 0.005f;
DN_Rules = Make;
FTimerHandle beginplayfirst_timer;
GetWorld()->GetTimerManager().SetTimer(beginplayfirst_timer, this, &ADayNightMPSky::UpdateSky, 0.2f, false);
}
// Called every frame
void ADayNightMPSky::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
class_DeltaTime = DeltaTime;
UpdateRealTime();
float something = (float)Month + (float)Day + SolarTime;
if ( HashVal != something )
{
HashVal = something;
}
if (DirectionalLight->Mobility.GetValue() == EComponentMobility::Movable)
{
UpdateSun();
}
if (SkyLight->Mobility.GetValue() == EComponentMobility::Movable)
{
if (UpdateSkySpamPrevention && !IsNight_B)
{
UpdateSkySpamPrevention = false;
UpdateSky();
//timer spam prevention
if (!tickfirst_timer_on)
{
tickfirst_timer_on = true;
GetWorld()->GetTimerManager().SetTimer(tickfirst_timer, this, &ADayNightMPSky::enableskyspam, 1.0f, false);
}
}
}
}
/*
*
*/
void ADayNightMPSky::UpdateSky()
{
if (::IsValid(SkyLight))
{
SkyLight->USkyLightComponent::RecaptureSky();
}
}
/*
*
*/
void ADayNightMPSky::UpdateSun()
{
int32 Hour_x, Minute_x, Second_x;
bool isDST_b = false;
FSunPositionData SunPositionDt;
FRotator MainRotator;
if (::IsValid(DirectionalLight))
{
GetHMSFromSolarTime(SolarTime, Hour_x, Minute_x, Second_x);
IsDST(UseDaylightSavingsTime, DSTStartMonth, DSTSTartDay, DSTEndMonth, DSTEndDay, DSTSwitchHours, isDST_b);
USunPositionFunctionLibrary::GetSunPosition(Latitude, Longitude, TimeZone, isDST_b, Year, Month, Day, Hour_x, Minute_x, Second_x, SunPositionDt);
Elevation = SunPositionDt.Elevation;
CorrectedElevation = SunPositionDt.CorrectedElevation;
Azimuth = SunPositionDt.Azimuth;
Sunrise = SunPositionDt.SunriseTime;
Sunset = SunPositionDt.SunsetTime;
//SunPositionDt.SolarNoon;
MainRotator = FRotator(CorrectedElevation, Azimuth + NorthOffset, 0.0f);
DirectionalLight->SetWorldRotation(MainRotator);
MainRotator.Pitch = MainRotator.Pitch - 180;
MoonLight->SetWorldRotation(MainRotator);
MoveMoon();
CompassMesh->SetWorldRotation(FRotator(0, NorthOffset + 90, 0).Quaternion());
}
}
/*
*
*/
void ADayNightMPSky::GetHMSFromSolarTime(float SolarTime_loc, int32& Hour, int32& Minute, int32& Second)
{
Hour = FMath::TruncToInt(SolarTime_loc) % 24;
Minute = FMath::TruncToInt((60 * (SolarTime_loc - (float)Hour))) % 60;
Second = FMath::TruncToInt((3600 * ((SolarTime_loc - Hour) - (Minute / 60))) + 0.5f) % 60;
}
/*
*
*/
void ADayNightMPSky::IsDST(bool DSTEnable, int32 DSTStartMonth_loc, int32 DSTStartDay_loc, int32 DSTEndMonth_loc, int32 DSTEndDa_loc, int32 DSTSwitchHour_loc, bool& isDST)
{
int32 Hour_x, Minute_x, Second_x;
GetHMSFromSolarTime(SolarTime, Hour_x, Minute_x, Second_x);
FDateTime Time_A = FDateTime(Year, Month, Day, Hour_x, Minute_x, Second_x);
FDateTime Time_B = FDateTime(Year, DSTStartMonth, DSTStartDay_loc, DSTSwitchHour_loc, 0, 0, 0);
FDateTime Time_C = FDateTime(Year, DSTEndMonth, DSTEndDa_loc, DSTSwitchHour_loc, 0, 0, 0);
if (Time_A >= Time_B && Time_A <= Time_C && DSTEnable)
{
isDST = true;
}
else
{
isDST = false;
}
}
/*
*
*/
void ADayNightMPSky::FromDateTime(FDateTime DateTime)
{
Year = DateTime.GetYear();
Month = DateTime.GetMonth();
Day = DateTime.GetDay();
float Second_l = (float)DateTime.GetSecond();
float Minute_l = (float)DateTime.GetMinute();
float Hour_l = (float)DateTime.GetHour();
float mid_a = Second_l * 0.01f;
float mid_b = (Second_l / 3) / 60.0f;
float mid_c = ((Minute_l) + mid_a + mid_b) / 60.0f;
float mid_d = (mid_c * 100.0f) * 0.01f;
SolarTime = Hour_l + mid_d;
}
/*
*
*/
void ADayNightMPSky::MoveMoon()
{
FRotator MoonRot = MoonLight->GetComponentRotation();
FLinearColor Color = FLinearColor(MoonRot.Vector());
if (::IsValid(SkyMaterial))
{
SkyMaterial->SetVectorParameterValue(FName(TEXT("Moon Sky Rotator")), Color);
}
}
/*
*
*/
void ADayNightMPSky::UpdateRealTime()
{
SetLocationRealTime();
FTimespan result = FDateTime::UtcNow() - DN_Rules.RealWorld_StaticStartTime;
float result_two = result.GetTotalSeconds() * (86400.0f / DN_Rules.RealWorldTimeInGameTime.GetTotalSeconds());
FTimespan time = FTimespan( 0, 0, 0, FMath::TruncToInt(result_two), FMath::TruncToInt(FMath::Fractional(result_two)) );
GameTimeNow = (DN_Rules.GameWorld_StaticStartTime + time) + UTCTimeDifference.TimeDifference;
FromDateTime(GameTimeNow);
SunIsDown();
SetMoon();
if (BeginDay == 0)
{
BeginDay = GameTimeNow.GetDay();
}
}
/*
*
*/
void ADayNightMPSky::SetLocationRealTime()
{
Latitude = DN_Rules.Latitude;
Longitude = DN_Rules.Longitude;
TimeZone = DN_Rules.TimeZone;
NorthOffset = DN_Rules.NorthOffset;
}
/*
*
*/
void ADayNightMPSky::SetMoon()
{
FLinearColor color = FLinearColor(DN_Rules.MoonSize, DN_Rules.MoonSize, DN_Rules.MoonSize, DN_Rules.MoonSize);
SkyMaterial->SetVectorParameterValue(FName(TEXT("Moon Radius")), color);
}
void ADayNightMPSky::SunIsDown()
{
FDateTime datesunset = FDateTime(GameTimeNow.GetYear(), GameTimeNow.GetMonth(), GameTimeNow.GetDay(), Sunset.GetHours(), Sunset.GetMinutes(), Sunset.GetSeconds(), 0);
FDateTime datesunrise = FDateTime(GameTimeNow.GetYear(), GameTimeNow.GetMonth(), GameTimeNow.GetDay(), Sunrise.GetHours(), Sunrise.GetMinutes(), Sunrise.GetSeconds(), 0);
if (GameTimeNow >= datesunset || GameTimeNow <= datesunrise)
{
//delegate
IsNight.Broadcast();
IsNight_B = true;
StarsOn();
ExponentialHeightFog->SetHiddenInGame(false);
DirectionalLight->SetIntensity(0.0f);
if (DN_Rules.Moon)
{
MoonLight->SetIntensity(DN_Rules.MoonLightStrength);
SkyMaterial->SetScalarParameterValue(FName(TEXT("Enable Moon")), 1.0f);
}
}
else
{
//delegate
IsDay.Broadcast();
IsNight_B = false;
StarsOff();
MoonLight->SetIntensity(0.0f);
ExponentialHeightFog->SetHiddenInGame(true);
DirectionalLight->SetIntensity(10.0f);
SkyMaterial->SetScalarParameterValue(FName(TEXT("Enable Moon")), 0.0f);
}
}
void ADayNightMPSky::StarsOn()
{
if (!StarsAreOn)
{
StarsAreOn = true;
//Timeline
StarsOnTimeline.PlayFromStart();
GetWorld()->GetTimerManager().SetTimer(StarsOnTimerHandle, this, &ADayNightMPSky::StarsOnTickTimeline, class_DeltaTime, true, 0.0f);
}
}
void ADayNightMPSky::StarsOnHelper(float Value)
{
SkyMaterial->SetScalarParameterValue(FName(TEXT("Stars brightness")), FMath::Clamp(Value, 0.0f, MaxStarsBrightness));
}
void ADayNightMPSky::StarsOff()
{
if (StarsAreOn)
{
StarsAreOn = false;
StarsOffTimeline.PlayFromStart();
GetWorld()->GetTimerManager().SetTimer(StarsOffTimerHandle, this, &ADayNightMPSky::StarsOffTickTimeline, class_DeltaTime, true, 0.0f);
}
}
void ADayNightMPSky::StarsOnTickTimeline()
{
if (StarsOnTimeline.IsPlaying())
{
StarsOnTimeline.TickTimeline(class_DeltaTime);
}
else
{
GetWorld()->GetTimerManager().ClearTimer(StarsOnTimerHandle);
SetLifeSpan(0);
}
}
void ADayNightMPSky::StarsOffTickTimeline()
{
if (StarsOffTimeline.IsPlaying())
{
StarsOffTimeline.TickTimeline(class_DeltaTime);
}
else
{
GetWorld()->GetTimerManager().ClearTimer(StarsOffTimerHandle);
SetLifeSpan(0);
}
}
void ADayNightMPSky::StarsOffHelper(float Value)
{
SkyMaterial->SetScalarParameterValue(FName(TEXT("Stars brightness")), FMath::Clamp(Value, 0.0f, MaxStarsBrightness));
}
/*
*
*/
void ADayNightMPSky::OnConstruction(const FTransform& Transform)
{
if (SkyMatFound != nullptr)
{
SkyMaterial = SkySphereMesh->CreateDynamicMaterialInstance(0, SkyMatFound);
}
//create material before these
UpdateSun();
UpdateSky();
}
/*
*
*/
void ADayNightMPSky::enableskyspam()
{
UpdateSkySpamPrevention = true;
tickfirst_timer_on = false;
}
Don’t forget the DayNightCycle_ST_Rules.h file which you can get from:
https://levelparadox.com/2020/10/06/ue4-day-and-night-cycle-for-multiplayer/2/
Also add SunPosition to MyProjectUE5.Build.cs file
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class MyProjectUE5 : ModuleRules
{
public MyProjectUE5(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "SunPosition" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}