diff --git a/LoadingScreen.uplugin b/LoadingScreen.uplugin index d120ee7..7abcc13 100644 --- a/LoadingScreen.uplugin +++ b/LoadingScreen.uplugin @@ -10,7 +10,6 @@ "CreatedByURL": "https://www.epicgames.com", "DocsURL": "https://github.com/ue4plugins/LoadingScreen", "SupportURL": "https://github.com/ue4plugins/LoadingScreen/issues", - "EngineVersion": "4.22", "EnabledByDefault": true, "CanContainContent": true, diff --git a/README.md b/README.md index a897293..50438f7 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,11 @@ The LoadingScreen plug-in implements a module that allows you to configure a sim Loading Screen system in the engine. To goal is to make it more customizable over time to avoid needing to write a new loading screen manually. +This is based off of Nick Darnell's version of the plugin which you can find [HERE](https://github.com/ue4plugins/LoadingScreen) ## Supported Platforms -This plug-in was last built against **Unreal Engine 4.22**. It works on all platforms (probably). +This plug-in was last built against **Unreal Engine 4.23**. It works on all platforms (probably). ## Dependencies @@ -39,9 +40,9 @@ The plug-in configured to be enabled by default once it's in your game's plug-in **Note: This plugin is not supported by Epic Games.** -Please [file an issue](https://github.com/nickdarnell/LoadingScreen/issues), -submit a [pull request](https://github.com/nickdarnell/LoadingScreen/pulls?q=is%3Aopen+is%3Apr) -or hit me up on twitter [@NickDarnell](https://twitter.com/NickDarnell) +Please [file an issue](https://github.com/Oldsiren/LoadingScreen/issues), +submit a [pull request](https://github.com/Oldsiren/LoadingScreen/pulls) +or hit me up on twitter [@Oldsiren](https://twitter.com/oldsiren) ## References diff --git a/Source/LoadingScreen/LoadingScreen.Build.cs b/Source/LoadingScreen/LoadingScreen.Build.cs index 0742db4..78aec13 100644 --- a/Source/LoadingScreen/LoadingScreen.Build.cs +++ b/Source/LoadingScreen/LoadingScreen.Build.cs @@ -1,27 +1,32 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. -namespace UnrealBuildTool.Rules +using UnrealBuildTool; +using System.IO; + +public class LoadingScreen : ModuleRules { - public class LoadingScreen : ModuleRules - { - public LoadingScreen(ReadOnlyTargetRules Target) - : base(Target) - { - PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + public LoadingScreen(ReadOnlyTargetRules Target) + : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); + PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private")); - PrivateIncludePaths.Add("LoadingScreen/Private"); + PublicDependencyModuleNames.AddRange( + new string[] { + "Core", + }); - PublicDependencyModuleNames.AddRange( - new string[] - { - "Core", - "CoreUObject", - "MoviePlayer", - "Slate", - "SlateCore", - "InputCore", - "Engine" - }); - } - } + PrivateDependencyModuleNames.AddRange( + new string[] { + "CoreUObject", + "MoviePlayer", + "Slate", + "SlateCore", + "InputCore", + "Engine" + }); + } } + diff --git a/Source/LoadingScreen/Private/LoadingScreenFunctionLibrary.cpp b/Source/LoadingScreen/Private/LoadingScreenFunctionLibrary.cpp new file mode 100644 index 0000000..190eb77 --- /dev/null +++ b/Source/LoadingScreen/Private/LoadingScreenFunctionLibrary.cpp @@ -0,0 +1,20 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "LoadingScreenFunctionLibrary.h" + + +FLoadingScreenDescription ULoadingScreenFunctionLibrary::GetStartupLoadingScreen() +{ + return GetDefault()->StartupScreen; +} + +FLoadingScreenDescription ULoadingScreenFunctionLibrary::GetDefaultLoadingScreen() +{ + return GetDefault()->DefaultScreen; +} + +void ULoadingScreenFunctionLibrary::SetLoadingScreen(FLoadingScreenDescription InDescription) +{ + GetMutableDefault()->DefaultScreen = InDescription; +} diff --git a/Source/LoadingScreen/Private/LoadingScreenModule.cpp b/Source/LoadingScreen/Private/LoadingScreenModule.cpp index fa72a55..c5bfcaf 100644 --- a/Source/LoadingScreen/Private/LoadingScreenModule.cpp +++ b/Source/LoadingScreen/Private/LoadingScreenModule.cpp @@ -23,7 +23,11 @@ class FLoadingScreenModule : public ILoadingScreenModule private: void HandlePrepareLoadingScreen(); - void BeginLoadingScreen(const FLoadingScreenDescription& ScreenDescription); + void HandleMovieClipFinished(const FString& FinishedClip); + + void BeginLoadingScreen(const FLoadingScreenDescription& ScreenDescription); + + TSharedPtr WidgetLoadingScreen; }; IMPLEMENT_MODULE(FLoadingScreenModule, LoadingScreen) @@ -43,15 +47,15 @@ void FLoadingScreenModule::StartupModule() { Ref.TryLoad(); } - for ( const FStringAssetReference& Ref : Settings->DefaultScreen.Images ) { Ref.TryLoad(); } if ( IsMoviePlayerEnabled() ) - { - GetMoviePlayer()->OnPrepareLoadingScreen().AddRaw(this, &FLoadingScreenModule::HandlePrepareLoadingScreen); + { + // Binds the delegate to auto fire the loading screen code when a level changes and when a movie finishes + GetMoviePlayer()->OnPrepareLoadingScreen().AddRaw(this, &FLoadingScreenModule::HandlePrepareLoadingScreen); } // Prepare the startup screen, the PrepareLoadingScreen callback won't be called @@ -64,6 +68,10 @@ void FLoadingScreenModule::ShutdownModule() { if ( !IsRunningDedicatedServer() ) { + if (WidgetLoadingScreen) + { + WidgetLoadingScreen.Reset(); + } GetMoviePlayer()->OnPrepareLoadingScreen().RemoveAll(this); } } @@ -74,8 +82,31 @@ void FLoadingScreenModule::HandlePrepareLoadingScreen() BeginLoadingScreen(Settings->DefaultScreen); } +void FLoadingScreenModule::HandleMovieClipFinished(const FString & FinishedClip) +{ + // If its not the last movie then try keep waiting + if (!GetMoviePlayer()->IsLastMovieInPlaylist()) + { + return; + } + + // Unbind the delegate so we're not firing this multiple times + GetMoviePlayer()->OnMovieClipFinished().RemoveAll(this); + + // Show the loading screen widget + if (WidgetLoadingScreen) + { + WidgetLoadingScreen->HandleMoviesFinishedPlaying(); + } +} + void FLoadingScreenModule::BeginLoadingScreen(const FLoadingScreenDescription& ScreenDescription) { + if (WidgetLoadingScreen) + { + WidgetLoadingScreen.Reset(); + } + FLoadingScreenAttributes LoadingScreen; LoadingScreen.MinimumLoadingScreenDisplayTime = ScreenDescription.MinimumLoadingScreenDisplayTime; LoadingScreen.bAutoCompleteWhenLoadingCompletes = ScreenDescription.bAutoCompleteWhenLoadingCompletes; @@ -83,13 +114,44 @@ void FLoadingScreenModule::BeginLoadingScreen(const FLoadingScreenDescription& S LoadingScreen.bWaitForManualStop = ScreenDescription.bWaitForManualStop; LoadingScreen.MoviePaths = ScreenDescription.MoviePaths; LoadingScreen.PlaybackType = ScreenDescription.PlaybackType; - - if ( ScreenDescription.bShowUIOverlay ) + + + if (ScreenDescription.bShowWidget) + { + // Create and store widget + WidgetLoadingScreen = SNew(SSimpleLoadingScreen, ScreenDescription) + .bShowThrobber(ScreenDescription.Throbber.bShowThrobber) + .ThrobberType(ScreenDescription.Throbber.ThrobberType) + ; + LoadingScreen.WidgetLoadingScreen = WidgetLoadingScreen; + } + + const bool IsPlayingValidMovies = LoadingScreen.MoviePaths.Num() != 0; + // Incase we have no movie paths, this will force it to show the loading screen anyway + if (!IsPlayingValidMovies) { - LoadingScreen.WidgetLoadingScreen = SNew(SSimpleLoadingScreen, ScreenDescription); + // Forces the movie player to create a movie streamer to actually show the widget and such + LoadingScreen.MoviePaths.Add(""); } + // If we have movies to show, then setup what happens if we're supposed to show ui otherwise skip this + else + { + // Edgecase + GetMoviePlayer()->OnMovieClipFinished().RemoveAll(this); + + GetMoviePlayer()->OnMovieClipFinished().AddRaw(this, &FLoadingScreenModule::HandleMovieClipFinished); + } + // This happens last after everything has been prepared ahead of time GetMoviePlayer()->SetupLoadingScreen(LoadingScreen); + + if (!IsPlayingValidMovies) + { + if (WidgetLoadingScreen) + { + WidgetLoadingScreen->HandleMoviesFinishedPlaying(); + } + } } diff --git a/Source/LoadingScreen/Private/LoadingScreenSettings.cpp b/Source/LoadingScreen/Private/LoadingScreenSettings.cpp index 6cabe7f..d6f0b5d 100644 --- a/Source/LoadingScreen/Private/LoadingScreenSettings.cpp +++ b/Source/LoadingScreen/Private/LoadingScreenSettings.cpp @@ -1,27 +1,80 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "LoadingScreenSettings.h" -#include "UObject/ConstructorHelpers.h" +#include "Styling/CoreStyle.h" #include "Engine/Font.h" +#include "UObject/ConstructorHelpers.h" #define LOCTEXT_NAMESPACE "LoadingScreen" -FLoadingScreenDescription::FLoadingScreenDescription() - : LoadingText(LOCTEXT("Loading", "LOADING")) +FLoadingScreenSlotPosition::FLoadingScreenSlotPosition() + : Anchors(0.5f) + , Offset(NoInit) + , Alignment(NoInit) +{ } + +FLoadingScreenSlotText::FLoadingScreenSlotText() + : bShouldShowText(true) + , TextJustification(ETextJustify::Center) + , WrapAt(1000.0f) + , TextColor(FSlateColor(FLinearColor::White)) { + if (!IsRunningDedicatedServer()) + { + static ConstructorHelpers::FObjectFinder RobotoFontObj(TEXT("/Engine/EngineFonts/Roboto")); + Font = FSlateFontInfo(RobotoFontObj.Object, 20, FName("Normal"));; + } +} + +FLoadingScreenText::FLoadingScreenText() + : SlotText(FLoadingScreenSlotText()) + , SlotPosition(FLoadingScreenSlotPosition()) +{ } + +FLoadingScreenThrobber::FLoadingScreenThrobber() + : bShowThrobber(true) + , ThrobberType(EThrobberLoadingType::TLT_Regular) + , bFlipThrobberAnimation(false) + , NumPiecesThrobber(6) + , ThrobberImage(*FCoreStyle::Get().GetBrush("Throbber.Chunk")) + , ThrobberSlotPosition(FLoadingScreenSlotPosition()) + , AnimateHorizontally(true) + , AnimateVertically(true) + , AnimateOpacity(true) + , ThrobberPeriod(0.75f) + , ThrobberRadius(16.0f) + , ImageBrush(*FCoreStyle::Get().GetDefaultBrush()) + , ImageColorAndOpacity(FLinearColor::White) +{ } + +FLoadingScreenTips::FLoadingScreenTips() + : SlotText(FLoadingScreenSlotText()) + , SlotPosition(FLoadingScreenSlotPosition()) + , TimeBetweenTips(0) +{ } + +FLoadingScreenDescription::FLoadingScreenDescription() + : bShowWidget(true) + , MinimumLoadingScreenDisplayTime(-1.0f) + , bAutoCompleteWhenLoadingCompletes(true) + , bMoviesAreSkippable(true) + , bWaitForManualStop(false) + , bShowUiOverlay(true) + , bShowUiAfterMovies(true) + , Throbber(FLoadingScreenThrobber()) + , LoadingScreenText(FLoadingScreenText()) + , LoadingScreenDescription(FLoadingScreenText()) + , LoadingScreenTips(FLoadingScreenTips()) + , bShowImagesAfterMovies(true) + , ImageStretch(EStretch::ScaleToFit) +{ + LoadingScreenText.Text = LOCTEXT("Loading", "LOADING"); } ULoadingScreenSettings::ULoadingScreenSettings(const FObjectInitializer& Initializer) : Super(Initializer) -{ - TipWrapAt = 1000.0f; +{ - if ( !IsRunningDedicatedServer() ) - { - static ConstructorHelpers::FObjectFinder RobotoFontObj(TEXT("/Engine/EngineFonts/Roboto")); - TipFont = FSlateFontInfo(RobotoFontObj.Object, 20, FName("Normal")); - LoadingFont = FSlateFontInfo(RobotoFontObj.Object, 32, FName("Bold")); - } } #undef LOCTEXT_NAMESPACE diff --git a/Source/LoadingScreen/Private/LoadingScreenSettings.h b/Source/LoadingScreen/Private/LoadingScreenSettings.h index ceb6936..b93ca88 100644 --- a/Source/LoadingScreen/Private/LoadingScreenSettings.h +++ b/Source/LoadingScreen/Private/LoadingScreenSettings.h @@ -3,67 +3,279 @@ #pragma once #include "CoreMinimal.h" +#include "Widgets/Layout/Anchors.h" #include "Fonts/SlateFontInfo.h" -#include "SScaleBox.h" #include "MoviePlayer.h" +#include "Widgets/Layout/SScaleBox.h" +#include "Framework/Text/TextLayout.h" #include "Engine/DeveloperSettings.h" #include "LoadingScreenSettings.generated.h" +UENUM(BlueprintType) +enum class EThrobberLoadingType : uint8 +{ + /** Uses a regular throbber to indicate loading */ + TLT_Regular UMETA(DisplayName = "Regular"), + /** Uses a circular throbber to indicate loading */ + TLT_Circular UMETA(DisplayName = "Circular"), + /** Uses an image instead of a throbber type incase you want to use an image with a material or something to indicate loading */ + TLT_Image UMETA(DisplayName = "Image") +}; + +USTRUCT(BlueprintType) +struct LOADINGSCREEN_API FLoadingScreenSlotPosition +{ + GENERATED_BODY() + +public: + + FLoadingScreenSlotPosition(); + + /** The anchor for the Widget + * 0-X = Left Side + * 1-X = Right Side + * 0-Y = Top Side + * 1-Y = Bottom Side + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Slot Position") + FAnchors Anchors; + + /** The offset for the Widget + * -X = Left + * +X = Right + * -Y = Up + * +Y = Down + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Slot Position") + FVector2D Offset; + + /** Alignment pivot point of the Widget with 0.5 being center of either axis + * 0-X = Left Side + * 1-X = Right Side + * 0-Y = Top Side + * 1-Y = Bottom Side + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Slot Position") + FVector2D Alignment; + +}; + +USTRUCT(BlueprintType) +struct LOADINGSCREEN_API FLoadingScreenSlotText +{ + GENERATED_BODY() + +public: + + FLoadingScreenSlotText(); + + /** Flag for showing the widget. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + bool bShouldShowText; + + /** The justification of the text. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + TEnumAsByte TextJustification; + + /** The size of the text before it's wrapped to the next line. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + float WrapAt; + + /** The color to use for the text */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading Screen Text") + FSlateColor TextColor; + + /** The font to display for text. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + FSlateFontInfo Font; +}; + +USTRUCT(BlueprintType) +struct LOADINGSCREEN_API FLoadingScreenText +{ + GENERATED_BODY() + +public: + + FLoadingScreenText(); + + /** Text Information related to the text */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading Screen Text") + FLoadingScreenSlotText SlotText; + + /** The slot position of the text */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading Screen Text") + FLoadingScreenSlotPosition SlotPosition; + + /** The text to display on the loading screen. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading Screen Text", meta = (MultiLine = "true")) + FText Text; + +}; + +USTRUCT(BlueprintType) +struct LOADINGSCREEN_API FLoadingScreenThrobber +{ + GENERATED_BODY() + +public: + + FLoadingScreenThrobber(); + + /** Flag for showing the loading throbber if true, false will not show any throbber. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber") + bool bShowThrobber; + + /** Decides which throbber type to show if true, false will not show any throbber. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber", meta = (EditCondition = "bShowThrobber")) + EThrobberLoadingType ThrobberType; + + /** Should throbber animate in opposite direction? Works for both regular and circular throbber */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber", meta = (EditCondition = "bShowThrobber")) + bool bFlipThrobberAnimation; + + /** The numbers of pieces in the throbber when it is shown */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber", meta = (ClampMin = "1", ClampMax = "25", EditCondition = "bShowThrobber")) + int NumPiecesThrobber; + + /** The image for each throbber piece */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber", meta = (EditCondition = "bShowThrobber")) + FSlateBrush ThrobberImage; + + /** The slot position of the throbber */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Throbber", meta = (EditCondition = "bShowThrobber")) + FLoadingScreenSlotPosition ThrobberSlotPosition; + + /** Should the pieces animate horizontally? */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Regular", meta = (EditCondition = "bShowThrobber")) + bool AnimateHorizontally; + + /** Should the pieces animate vertically? */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Regular", meta = (EditCondition = "bShowThrobber")) + bool AnimateVertically; + + /** Should the pieces animate their opacity? */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Regular", meta = (EditCondition = "bShowThrobber")) + bool AnimateOpacity; + + /** The amount of time for a full circle(in seconds) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Circular", meta = (EditCondition = "bShowThrobber")) + float ThrobberPeriod; + + /** The radius of the circle */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Circular", meta = (EditCondition = "bShowThrobber")) + float ThrobberRadius; + + /** Image to draw (adjust image size here to adjust the size in X and Y) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Image", meta = (EditCondition = "bShowThrobber")) + FSlateBrush ImageBrush; + + /** Color and opacity */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Image", meta = (EditCondition = "bShowThrobber", sRGB = "true")) + FLinearColor ImageColorAndOpacity; + +}; + +USTRUCT(BlueprintType) +struct LOADINGSCREEN_API FLoadingScreenTips +{ + GENERATED_BODY() + +public: + + FLoadingScreenTips(); + + /** Text Information related to the tips text */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + FLoadingScreenSlotText SlotText; + + /** The slot position of the tips */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips") + FLoadingScreenSlotPosition SlotPosition; + + /** The intended time between tips before it automatically switches to a new tip, anything below zero will cause the tips to not change. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips", meta = (ClampMin = "0")) + int TimeBetweenTips; // Using an integer because letting people be able to get it really low might be bad... + + /** The tips to display on the load screen */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tips", meta =(MultiLine = "true")) + TArray Tips; + +}; + USTRUCT(BlueprintType) struct LOADINGSCREEN_API FLoadingScreenDescription { - GENERATED_USTRUCT_BODY() + GENERATED_BODY() + +public: FLoadingScreenDescription(); + /** Flag for showing any ui elements and images if true(incase you only want to show movies and thats it then set this to false) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Loading") + bool bShowWidget; + /** The minimum time that a loading screen should be opened for, -1 if there is no minimum time. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Loading) - float MinimumLoadingScreenDisplayTime = -1; - + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Loading") + float MinimumLoadingScreenDisplayTime; + /** If true, the loading screen will disappear as soon as loading is done. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Loading) - bool bAutoCompleteWhenLoadingCompletes = true; - + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Loading") + bool bAutoCompleteWhenLoadingCompletes; + /** If true, movies can be skipped by clicking the loading screen as long as loading is done. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Loading) - bool bMoviesAreSkippable = true; - + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Loading") + bool bMoviesAreSkippable; + /** If true, movie playback continues until Stop is called. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Loading) - bool bWaitForManualStop = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Loading") + bool bWaitForManualStop; /** Should we just play back, loop, etc. NOTE: if playback type is MT_LoadingLoop, then MoviePlayer will auto complete when in the last movie and load finishes regardless of bAutoCompleteWhenLoadingCompletes */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Loading) - TEnumAsByte PlaybackType; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Movies") + TEnumAsByte PlaybackType; /** The movie paths local to the game's Content/Movies/ directory without extension. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Movies) - TArray MoviePaths; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|Movies") + TArray MoviePaths; - /** Should we show the images/tips/loading text? Generally you'll want to set this to false if you just want to show a movie. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Display) - bool bShowUIOverlay = true; + /** Should we show the throbber/loading text etc? Generally you'll want to set this to false if you just want to show a movie. This will render over any movie/background image. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI") + bool bShowUiOverlay; - /** Text displayed beside the animated icon */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Display) - FText LoadingText; + /** Flag for showing UI after all movies have been played successfully if true. False will show during movies. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI", meta = (EditCondition = "bShowUIOverlay")) + bool bShowUiAfterMovies; - /** The texture display while in the loading screen on top of the movie. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Images, meta=(AllowedClasses="Texture2D")) - TArray Images; + /** Throbber to display when loading, can show circular and regular throbber types */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Throbber", meta = (EditCondition = "bShowUIOverlay")) + FLoadingScreenThrobber Throbber; - /** The scaling type to apply to images. */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Images) - TEnumAsByte ImageStretch = EStretch::ScaleToFit; + /** Text to display to indicate that the game is loading */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Loading Text", meta = (EditCondition = "bShowUIOverlay")) + FLoadingScreenText LoadingScreenText; + + /** Optional text to display as a description. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Description", meta = (EditCondition = "bShowUIOverlay")) + FLoadingScreenText LoadingScreenDescription; + + /** Optional text to display that will randomly swap out with other tips if applicable */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Tips", meta = (EditCondition = "bShowUIOverlay")) + FLoadingScreenTips LoadingScreenTips; + + /** Flag for showing images after all movies have been played successfully if true. False will show during movies. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Images") + bool bShowImagesAfterMovies; - /** The background color to use */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Images) - FLinearColor BackgroundColor = FLinearColor::Black; + /** The texture display while in the loading screen on top of the movie. Will render after and over any movies. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Images", meta = (AllowedClasses = "Texture2D")) + TArray Images; - /** The background color to use for tips */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Images) - FLinearColor TipBackgroundColor = FLinearColor(0, 0, 0, 0.75f); + /** The scaling type to apply to images. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Screens|UI|Images") + TEnumAsByte ImageStretch; }; /** @@ -72,31 +284,18 @@ struct LOADINGSCREEN_API FLoadingScreenDescription UCLASS(config=Game, defaultconfig, meta=(DisplayName="Loading Screen")) class LOADINGSCREEN_API ULoadingScreenSettings : public UDeveloperSettings { - GENERATED_UCLASS_BODY() + GENERATED_BODY() public: + ULoadingScreenSettings(const FObjectInitializer& Initializer); + /** The startup screen for the project. */ - UPROPERTY(config, EditAnywhere, Category=Screens) + UPROPERTY(config, EditAnywhere, Category = "Screens") FLoadingScreenDescription StartupScreen; /** The default load screen between maps. */ - UPROPERTY(config, EditAnywhere, Category=Screens) + UPROPERTY(config, EditAnywhere, Category = "Screens") FLoadingScreenDescription DefaultScreen; - /** The font to display the tips in. */ - UPROPERTY(config, EditAnywhere, BlueprintReadWrite, Category=Advice) - FSlateFontInfo TipFont; - - /** The font to display on loading. */ - UPROPERTY(config, EditAnywhere, BlueprintReadWrite, Category = Display) - FSlateFontInfo LoadingFont; - - /** The size of the tip before it's wrapped to the next line. */ - UPROPERTY(config, EditAnywhere, BlueprintReadWrite, Category=Advice) - float TipWrapAt; - - /** The tips to display on the load screen. */ - UPROPERTY(config, EditAnywhere, BlueprintReadWrite, Category=Advice, meta = (MultiLine = "true")) - TArray Tips; }; diff --git a/Source/LoadingScreen/Private/SSimpleLoadingScreen.cpp b/Source/LoadingScreen/Private/SSimpleLoadingScreen.cpp index b80a27c..d7e69ce 100644 --- a/Source/LoadingScreen/Private/SSimpleLoadingScreen.cpp +++ b/Source/LoadingScreen/Private/SSimpleLoadingScreen.cpp @@ -2,19 +2,22 @@ #include "SSimpleLoadingScreen.h" -#include "Widgets/SOverlay.h" -#include "Widgets/SBoxPanel.h" +#include "Slate/DeferredCleanupSlateBrush.h" #include "Widgets/Layout/SScaleBox.h" +#include "Widgets/Images/SImage.h" #include "Widgets/Layout/SSpacer.h" -#include "Widgets/Layout/SBorder.h" -#include "Widgets/Layout/SSafeZone.h" +#include "Widgets/SOverlay.h" +#include "Widgets/SBoxPanel.h" #include "Widgets/Layout/SDPIScaler.h" #include "Widgets/Text/STextBlock.h" -#include "Widgets/Images/SImage.h" +#include "Widgets/Layout/SBorder.h" +#include "Widgets/Layout/SConstraintCanvas.h" +#include "Widgets/Layout/SSafeZone.h" #include "Widgets/Images/SThrobber.h" +#include "Framework/Application/SlateApplication.h" #include "Engine/Texture2D.h" +#include "Engine/Engine.h" #include "Engine/UserInterfaceSettings.h" -#include "Slate/DeferredCleanupSlateBrush.h" #define LOCTEXT_NAMESPACE "LoadingScreen" @@ -22,8 +25,7 @@ // SSimpleLoadingScreen static float PointSizeToSlateUnits(float PointSize) -{ - //FreeTypeConstants::HorizontalDPI = 96; +{ const float SlateFreeTypeHorizontalResolutionDPI = 96.0f; const float FreeTypeNativeDPI = 72.0f; const float PixelSize = PointSize * (SlateFreeTypeHorizontalResolutionDPI / FreeTypeNativeDPI); @@ -32,128 +34,290 @@ static float PointSizeToSlateUnits(float PointSize) } void SSimpleLoadingScreen::Construct(const FArguments& InArgs, const FLoadingScreenDescription& InScreenDescription) -{ - const ULoadingScreenSettings* Settings = GetDefault(); +{ + LastToolTipUpdate = -1.0f; + + ScreenDescriptionInfo = InScreenDescription; - const FSlateFontInfo& TipFont = Settings->TipFont; - const FSlateFontInfo& LoadingFont = Settings->LoadingFont; + // Only show on construct if UI is true and we're not showing it after movies + const bool bShowUiOnConstruct = (ScreenDescriptionInfo.bShowUiOverlay && !ScreenDescriptionInfo.bShowUiAfterMovies); + bShowThrobber = InArgs._bShowThrobber; + ThrobberType = InArgs._ThrobberType; + // Construct the root of this widget TSharedRef Root = SNew(SOverlay); // If there's an image defined - if ( InScreenDescription.Images.Num() > 0 ) + if (ScreenDescriptionInfo.Images.Num() > 0) { - const int32 ImageIndex = FMath::RandRange(0, InScreenDescription.Images.Num() - 1); - const FStringAssetReference& ImageAsset = InScreenDescription.Images[ImageIndex]; + // Construct a random image to use for the loading screen + const int32 ImageIndex = FMath::RandRange(0, ScreenDescriptionInfo.Images.Num() - 1); + const FStringAssetReference& ImageAsset = ScreenDescriptionInfo.Images[ImageIndex]; UObject* ImageObject = ImageAsset.TryLoad(); if ( UTexture2D* LoadingImage = Cast(ImageObject) ) { - LoadingScreenBrush = FDeferredCleanupSlateBrush::CreateBrush(LoadingImage); + FVector2D Size = FVector2D(LoadingImage->GetSizeX(), LoadingImage->GetSizeY()); + LoadingScreenBrush = FDeferredCleanupSlateBrush::CreateBrush(LoadingImage, Size); + //LoadingImage, Size, FName(*ImageAsset.ToString())) + // Adds a slot to the root then add that image to the widget, renders over the movie if supposed to + BackgroundImageWidget = SNew(SImage) + .Visibility(ScreenDescriptionInfo.bShowImagesAfterMovies ? EVisibility::Hidden : EVisibility::SelfHitTestInvisible) + .Image(LoadingScreenBrush->GetSlateBrush()); - Root->AddSlot() + Root->AddSlot(0) .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) + .VAlign(VAlign_Fill) [ - SNew(SBorder) - .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) - .BorderBackgroundColor(InScreenDescription.BackgroundColor) - .BorderImage(FCoreStyle::Get().GetBrush("WhiteBrush")) + SNew(SScaleBox) + .Stretch(ScreenDescriptionInfo.ImageStretch) [ - SNew(SScaleBox) - .Stretch(InScreenDescription.ImageStretch) - [ - SNew(SImage) - .Image(LoadingScreenBrush.IsValid() ? LoadingScreenBrush->GetSlateBrush() : nullptr) - ] + BackgroundImageWidget.ToSharedRef() ] ]; } - } + } - TSharedRef TipWidget = SNullWidget::NullWidget; - if ( Settings->Tips.Num() > 0 ) + // Handles creating the throbber widget { - const int32 TipIndex = FMath::RandRange(0, Settings->Tips.Num() - 1); + // Decides which throbber type to show + switch (ThrobberType) + { + case EThrobberLoadingType::TLT_Circular: + { + // Construct circular throbber + TSharedPtr ConstructedThrobber = SNew(SCircularThrobber) + .Radius(ScreenDescriptionInfo.Throbber.ThrobberRadius) + .Period(ScreenDescriptionInfo.Throbber.ThrobberPeriod) + .NumPieces(ScreenDescriptionInfo.Throbber.NumPiecesThrobber) + .PieceImage(&ScreenDescriptionInfo.Throbber.ThrobberImage); + + ThrobberWidget = ConstructedThrobber; + break; + } + case EThrobberLoadingType::TLT_Regular: + { + // Decide which animation to play for regular throbber + const int32 AnimationParams = (ScreenDescriptionInfo.Throbber.AnimateVertically ? SThrobber::Vertical : 0) | + (ScreenDescriptionInfo.Throbber.AnimateHorizontally ? SThrobber::Horizontal : 0) | + (ScreenDescriptionInfo.Throbber.AnimateOpacity ? SThrobber::Opacity : 0); + const SThrobber::EAnimation Animation = static_cast(AnimationParams); + + // Construct regular throbber + TSharedPtr ConstructedThrobber = SNew(SThrobber) + .Animate(Animation) + .NumPieces(ScreenDescriptionInfo.Throbber.NumPiecesThrobber) + .PieceImage(&ScreenDescriptionInfo.Throbber.ThrobberImage); + + ThrobberWidget = ConstructedThrobber; + break; + } + case EThrobberLoadingType::TLT_Image: + default: + { + // Setup image to show + const FSlateBrush* ImageBrush = &ScreenDescriptionInfo.Throbber.ImageBrush; - TipWidget = SNew(STextBlock) - .WrapTextAt(Settings->TipWrapAt) - .Font(TipFont) - .Text(Settings->Tips[TipIndex]); + // Construct an image in place of throbber + TSharedPtr ConstructedImage = SNew(SImage) + .Image(ImageBrush) + .ColorAndOpacity(ScreenDescriptionInfo.Throbber.ImageColorAndOpacity); + + ThrobberWidget = ConstructedImage; + break; + } + } + + // Only adjust the the scaling if we're not using an image + if (ThrobberType != EThrobberLoadingType::TLT_Image) + { + // Handles flipping the throbber if needed + ThrobberWidget->SetRenderTransformPivot(FVector2D(0.5f, 0.5f)); + const float ThrobberScale = (float)((ScreenDescriptionInfo.Throbber.bFlipThrobberAnimation) ? -1 : 1); + ThrobberWidget->SetRenderTransform(FSlateRenderTransform(FScale2D(ThrobberScale, 1.0f))); + } + // Show throbber if allowed + ThrobberWidget->SetVisibility((bShowThrobber && bShowUiOnConstruct) ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); } - else - { - // Need to use a spacer when being rendered on another thread, incrementing the SNullWidget will - // lead to shared ptr crashes. - TipWidget = SNew(SSpacer); + + // Construct tooltip widget + CurrentToolTipWidget = SNew(STextBlock) + .Visibility(EVisibility::Hidden) // Default to hidden just incase + .WrapTextAt(ScreenDescriptionInfo.LoadingScreenTips.SlotText.WrapAt) + .Font(ScreenDescriptionInfo.LoadingScreenTips.SlotText.Font) + .ColorAndOpacity(ScreenDescriptionInfo.LoadingScreenTips.SlotText.TextColor) + .Justification(ScreenDescriptionInfo.LoadingScreenTips.SlotText.TextJustification); + + // Handles creating the tip text widget + if (ScreenDescriptionInfo.LoadingScreenTips.Tips.Num() > 0) + { + // Decide tool tip to show + CurrentToolTipIndex = FMath::RandRange(0, ScreenDescriptionInfo.LoadingScreenTips.Tips.Num() - 1); + + // Update the text + CurrentToolTipWidget->SetText(ScreenDescriptionInfo.LoadingScreenTips.Tips[CurrentToolTipIndex]); + // Show tooltip widget if allowed + CurrentToolTipWidget->SetVisibility((ScreenDescriptionInfo.LoadingScreenTips.SlotText.bShouldShowText && bShowUiOnConstruct) + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + + // For deciding the time between tooltips + LastToolTipUpdate = FPlatformTime::Seconds(); } + // Construct Description Text + DescriptionTextWidget = SNew(STextBlock) + .Text(ScreenDescriptionInfo.LoadingScreenDescription.Text) + .Font(ScreenDescriptionInfo.LoadingScreenDescription.SlotText.Font) + .ColorAndOpacity(ScreenDescriptionInfo.LoadingScreenDescription.SlotText.TextColor) + .Justification(ScreenDescriptionInfo.LoadingScreenDescription.SlotText.TextJustification) + .WrapTextAt(ScreenDescriptionInfo.LoadingScreenDescription.SlotText.WrapAt) + .Visibility((ScreenDescriptionInfo.LoadingScreenDescription.SlotText.bShouldShowText && bShowUiOnConstruct) + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + + // Construct Loading text + LoadingTextWidget = SNew(STextBlock) + .Text(ScreenDescriptionInfo.LoadingScreenText.Text) + .Font(ScreenDescriptionInfo.LoadingScreenText.SlotText.Font) + .ColorAndOpacity(ScreenDescriptionInfo.LoadingScreenText.SlotText.TextColor) + .Justification(ScreenDescriptionInfo.LoadingScreenText.SlotText.TextJustification) + .Visibility((ScreenDescriptionInfo.LoadingScreenText.SlotText.bShouldShowText && bShowUiOnConstruct) + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + + // Adds a slot to the root of this widget to allow for other widgets to be added to it, renders over image/movie Root->AddSlot() .HAlign(HAlign_Fill) - .VAlign(VAlign_Bottom) + .VAlign(VAlign_Fill) [ - SNew(SBorder) - .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) - .BorderBackgroundColor(InScreenDescription.TipBackgroundColor) - .BorderImage(FCoreStyle::Get().GetBrush("WhiteBrush")) + SNew(SSafeZone) [ - SNew(SSafeZone) - .HAlign(HAlign_Fill) - .VAlign(VAlign_Bottom) - .IsTitleSafe(true) - [ - SNew(SDPIScaler) - .DPIScale(this, &SSimpleLoadingScreen::GetDPIScale) - [ - SNew(SHorizontalBox) - - + SHorizontalBox::Slot() - .Padding(FMargin(25, 0.0f, 0, 0)) - .VAlign(VAlign_Center) - .AutoWidth() - [ - SNew(SCircularThrobber) - .Radius(PointSizeToSlateUnits(LoadingFont.Size) / 2.0f) - ] - - + SHorizontalBox::Slot() - .Padding(FMargin(40.0f, 0.0f, 0, 0)) - .AutoWidth() - .VAlign(VAlign_Center) - [ - SNew(STextBlock) - .Text(InScreenDescription.LoadingText) - .Font(LoadingFont) - ] - - + SHorizontalBox::Slot() - .FillWidth(1) - .HAlign(HAlign_Fill) - [ - SNew(SSpacer) - .Size(FVector2D(1.0f, 1.0f)) - ] - - + SHorizontalBox::Slot() - .AutoWidth() - .HAlign(HAlign_Right) - .VAlign(VAlign_Center) - .Padding(FMargin(10.0f)) - [ - TipWidget - ] - ] - ] + SNew(SConstraintCanvas) + + // Adds the circular throbber to the canvas + + SConstraintCanvas::Slot() + .Anchors(ScreenDescriptionInfo.Throbber.ThrobberSlotPosition.Anchors) + .Offset(FMargin(ScreenDescriptionInfo.Throbber.ThrobberSlotPosition.Offset)) + .Alignment(ScreenDescriptionInfo.Throbber.ThrobberSlotPosition.Alignment) + .AutoSize(true) + .ZOrder(1) + [ + ThrobberWidget.ToSharedRef() + ] + + // Adds the tip text to the canvas + + SConstraintCanvas::Slot() + .Anchors(ScreenDescriptionInfo.LoadingScreenTips.SlotPosition.Anchors) + .Offset(FMargin(ScreenDescriptionInfo.LoadingScreenTips.SlotPosition.Offset)) + .Alignment(ScreenDescriptionInfo.LoadingScreenTips.SlotPosition.Alignment) + .AutoSize(true) + .ZOrder(1) + [ + CurrentToolTipWidget.ToSharedRef() + ] + + // Adds the description text to the canvas + + SConstraintCanvas::Slot() + .Anchors(ScreenDescriptionInfo.LoadingScreenDescription.SlotPosition.Anchors) + .Offset(FMargin(ScreenDescriptionInfo.LoadingScreenDescription.SlotPosition.Offset)) + .Alignment(ScreenDescriptionInfo.LoadingScreenDescription.SlotPosition.Alignment) + .AutoSize(true) + .ZOrder(2) + [ + DescriptionTextWidget.ToSharedRef() ] - ]; + // Adds the loading text to the canvas + + SConstraintCanvas::Slot() + .Anchors(ScreenDescriptionInfo.LoadingScreenText.SlotPosition.Anchors) + .Offset(FMargin(ScreenDescriptionInfo.LoadingScreenText.SlotPosition.Offset)) + .Alignment(ScreenDescriptionInfo.LoadingScreenText.SlotPosition.Alignment) + .AutoSize(true) + .ZOrder(3) + [ + LoadingTextWidget.ToSharedRef() + ] + ] + ]; + ChildSlot [ Root ]; } +void SSimpleLoadingScreen::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) +{ + // Dont continue if we only have 1 tip to show + if (ScreenDescriptionInfo.LoadingScreenTips.Tips.Num() == 1) + { + return; + } + + const int TipDelay = ScreenDescriptionInfo.LoadingScreenTips.TimeBetweenTips; + + // Dont continue if the delay time is at zero + if (TipDelay == 0) + { + return; + } + // If the time between now and last tooltip update is longer than the intended delay + else if ((InCurrentTime - LastToolTipUpdate) > TipDelay) + { + // Record the time + LastToolTipUpdate = InCurrentTime; + + // Valid check + if (CurrentToolTipWidget) + { + // Update the text to a new random tool tip + CurrentToolTipWidget->SetText(GetRandomToolTip()); + } + } +} + +void SSimpleLoadingScreen::HandleMoviesFinishedPlaying() +{ + // Show the background if we're allowed to + if (ScreenDescriptionInfo.bShowImagesAfterMovies) + { + if (BackgroundImageWidget) + { + BackgroundImageWidget->SetVisibility(EVisibility::SelfHitTestInvisible); + } + } + + // Show ui elements if we're showing ui and we can show it after movies + if (ScreenDescriptionInfo.bShowUiAfterMovies && ScreenDescriptionInfo.bShowUiOverlay) + { + if (ThrobberWidget) + { + ThrobberWidget->SetVisibility(ScreenDescriptionInfo.Throbber.bShowThrobber + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + } + + if (LoadingTextWidget) + { + LoadingTextWidget->SetVisibility(ScreenDescriptionInfo.LoadingScreenText.SlotText.bShouldShowText + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + } + + if (DescriptionTextWidget) + { + DescriptionTextWidget->SetVisibility(ScreenDescriptionInfo.LoadingScreenDescription.SlotText.bShouldShowText + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + } + + // Only show tooltip widget if we have any tips to show + if (CurrentToolTipWidget && ScreenDescriptionInfo.LoadingScreenTips.Tips.Num() != 0) + { + // Reset the time so incase if when we're visible its not shorter than its supposed to be + LastToolTipUpdate = FPlatformTime::Seconds(); + + + CurrentToolTipWidget->SetVisibility(ScreenDescriptionInfo.LoadingScreenTips.SlotText.bShouldShowText + ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden); + } + } +} + float SSimpleLoadingScreen::GetDPIScale() const { const FVector2D& DrawSize = GetCachedGeometry().ToPaintGeometry().GetLocalSize(); @@ -161,4 +325,37 @@ float SSimpleLoadingScreen::GetDPIScale() const return GetDefault()->GetDPIScaleBasedOnSize(Size); } +FText SSimpleLoadingScreen::GetRandomToolTip() +{ + // Decides a random tip to show thats not the current tooltip + { + const int32 Total = ScreenDescriptionInfo.LoadingScreenTips.Tips.Num(); + int32 RandomTip = FMath::RandRange(0, Total - 1); + // If there's only one then do nothing + if (Total == 1) + { + RandomTip = 0; + } + else + { + // Find a random index that is not currently used + while (RandomTip == CurrentToolTipIndex) + { + // Randomize the index + RandomTip = FMath::RandRange(0, Total - 1); + } + } + + // Update current index to be this randomized one + CurrentToolTipIndex = RandomTip; + } + + return ScreenDescriptionInfo.LoadingScreenTips.Tips[CurrentToolTipIndex]; +} + +bool SSimpleLoadingScreen::CanShowToolTip() const +{ + return (ScreenDescriptionInfo.LoadingScreenTips.Tips.Num() > 0); +} + #undef LOCTEXT_NAMESPACE diff --git a/Source/LoadingScreen/Private/SSimpleLoadingScreen.h b/Source/LoadingScreen/Private/SSimpleLoadingScreen.h index 91fab88..245e028 100644 --- a/Source/LoadingScreen/Private/SSimpleLoadingScreen.h +++ b/Source/LoadingScreen/Private/SSimpleLoadingScreen.h @@ -1,25 +1,55 @@ -// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #pragma once -#include "SCompoundWidget.h" +#include "SlateCore/Public/Widgets/SCompoundWidget.h" +#include "Styling/CoreStyle.h" #include "LoadingScreenSettings.h" class FDeferredCleanupSlateBrush; +class STextBlock; +class SImage; class SSimpleLoadingScreen : public SCompoundWidget { public: - SLATE_BEGIN_ARGS(SSimpleLoadingScreen) {} - + SLATE_BEGIN_ARGS(SSimpleLoadingScreen) : + _bShowThrobber(false), + _ThrobberType(EThrobberLoadingType::TLT_Regular) + {} + SLATE_ARGUMENT(bool, bShowThrobber); + SLATE_ARGUMENT(EThrobberLoadingType, ThrobberType); SLATE_END_ARGS() void Construct(const FArguments& InArgs, const FLoadingScreenDescription& ScreenDescription); + virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; + + /** Handles setting visibility on objects that should be showing after all loading movies finished showing */ + void HandleMoviesFinishedPlaying(); + private: float GetDPIScale() const; + + /** Returns a random tool tip that is not currently used and sets the current index to that new one */ + FText GetRandomToolTip(); + + /** Checks if we're able to show any tool tips */ + bool CanShowToolTip() const; -private: - TSharedPtr LoadingScreenBrush; + TSharedPtr LoadingScreenBrush; + + bool bShowThrobber; + EThrobberLoadingType ThrobberType; + + double LastToolTipUpdate; + int CurrentToolTipIndex; + TSharedPtr CurrentToolTipWidget; + TSharedPtr LoadingTextWidget; + TSharedPtr DescriptionTextWidget; + TSharedPtr ThrobberWidget = SNullWidget::NullWidget; + TSharedPtr BackgroundImageWidget; + + FLoadingScreenDescription ScreenDescriptionInfo; }; diff --git a/Source/LoadingScreen/Public/ILoadingScreenModule.h b/Source/LoadingScreen/Public/ILoadingScreenModule.h index b5b5294..55e2204 100644 --- a/Source/LoadingScreen/Public/ILoadingScreenModule.h +++ b/Source/LoadingScreen/Public/ILoadingScreenModule.h @@ -2,7 +2,7 @@ #pragma once -#include "ModuleManager.h" +#include "Modules/ModuleManager.h" /** * The public interface to this module diff --git a/Source/LoadingScreen/Public/LoadingScreenFunctionLibrary.h b/Source/LoadingScreen/Public/LoadingScreenFunctionLibrary.h new file mode 100644 index 0000000..0c24cfc --- /dev/null +++ b/Source/LoadingScreen/Public/LoadingScreenFunctionLibrary.h @@ -0,0 +1,35 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "LoadingScreenSettings.h" +#include "LoadingScreenFunctionLibrary.generated.h" + +/** + * + */ +UCLASS() +class LOADINGSCREEN_API ULoadingScreenFunctionLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + + /** Returns the startup loading screen settings */ + UFUNCTION(BlueprintPure, Category = "Loading Screen") + static FLoadingScreenDescription GetStartupLoadingScreen(); + + /** Returns the current default loading screen settings. */ + UFUNCTION(BlueprintPure, Category = "Loading Screen") + static FLoadingScreenDescription GetDefaultLoadingScreen(); + + /** + * Sets the current default loading screen settings to InDescription. + * NOTE: This by default does not save those changes so when the application closes, it will reset those settings. + */ + UFUNCTION(BlueprintCallable, Category = "Loading Screen") + static void SetLoadingScreen(FLoadingScreenDescription InDescription); + +};