In this post we’re going to see how to create a basic File Picker inside Unreal Engine. We’re going to use the built-in tools that the engine provides and read a text file.

Adding the required Dependencies

For this post I have created a C++ project using the 4.20 version of the engine. Then, I added the SlateCore dependency in the public module names in the <MyProject>.Build.cs file:

PublicDependencyModuleNames . AddRange ( new string [ ] { "Core" , "CoreUObject" , "Engine" , "InputCore" , "HeadMountedDisplay" , "SlateCore" } ) ;

Creating the file picker

Ideally, you will place the functionality of the file picker in a utility library so you can use it throughout your project. However I’ve added the code inside the character code just for demonstration purposes.

I have created two functions, one that is responsible for opening and displaying the file picker and one which is responsible for getting the contents of the selected file:

Character header file /* * Opens a file dialog for the specified data. Leave FileTypes empty to be able to select any files. * Filetypes must be in the format of: <File type Description>|*.<actual extension> * You can combine multiple extensions by placing ";" between them * For example: Text Files|*.txt|Excel files|*.csv|Image Files|*.png;*.jpg;*.bmp will display 3 lines for 3 different type of files. */ UFUNCTION(BlueprintCallable, Category = "FilePicker") void OpenFileDialog(const FString& DialogTitle, const FString& DefaultPath, const FString& FileTypes, TArray<FString>& OutFileNames); /*Prints the data of the given file*/ UFUNCTION(BlueprintCallable, Category = "FilePicker") void PrintData(const FString& File); 1 2 3 4 5 6 7 8 9 10 11 12 /* * Opens a file dialog for the specified data. Leave FileTypes empty to be able to select any files. * Filetypes must be in the format of: <File type Description>|*.<actual extension> * You can combine multiple extensions by placing ";" between them * For example: Text Files|*.txt|Excel files|*.csv|Image Files|*.png;*.jpg;*.bmp will display 3 lines for 3 different type of files. */ UFUNCTION ( BlueprintCallable , Category = "FilePicker" ) void OpenFileDialog ( const FString & DialogTitle , const FString & DefaultPath , const FString & FileTypes , TArray < FString > & OutFileNames ) ; /*Prints the data of the given file*/ UFUNCTION ( BlueprintCallable , Category = "FilePicker" ) void PrintData ( const FString & File ) ;

Before implementing the logic for each function, make sure to include the following header files in your class:

Includes //File picker includes #include "Developer/DesktopPlatform/Public/IDesktopPlatform.h" #include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h" 1 2 3 //File picker includes #include "Developer/DesktopPlatform/Public/IDesktopPlatform.h" #include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"

The reason we need to include them is so we can have access to the deskplatform code where the built-in file picker exists.

Here’s the implementation of each function:

Functions implementations void AFilePickerCharacter::OpenFileDialog(const FString& DialogTitle, const FString& DefaultPath, const FString& FileTypes, TArray<FString>& OutFileNames) { if (GEngine) { if (GEngine->GameViewport) { void* ParentWindowHandle = GEngine->GameViewport->GetWindow()->GetNativeWindow()->GetOSWindowHandle(); IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get(); if (DesktopPlatform) { //Opening the file picker! uint32 SelectionFlag = 0; //A value of 0 represents single file selection while a value of 1 represents multiple file selection DesktopPlatform->OpenFileDialog(ParentWindowHandle, DialogTitle, DefaultPath, FString(""), FileTypes, SelectionFlag, OutFileNames); } } } } void AFilePickerCharacter::PrintData(const FString& File) { //Parse the data into a string array TArray<FString> LoadedText; FFileHelper::LoadFileToStringArray(LoadedText, *File); //Print the contents for (int32 i = 0; i < LoadedText.Num(); i++) { GLog->Log(LoadedText[i]); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 void AFilePickerCharacter :: OpenFileDialog ( const FString & DialogTitle , const FString & DefaultPath , const FString & FileTypes , TArray < FString > & OutFileNames ) { if ( GEngine ) { if ( GEngine -> GameViewport ) { void * ParentWindowHandle = GEngine -> GameViewport -> GetWindow ( ) -> GetNativeWindow ( ) -> GetOSWindowHandle ( ) ; IDesktopPlatform * DesktopPlatform = FDesktopPlatformModule :: Get ( ) ; if ( DesktopPlatform ) { //Opening the file picker! uint32 SelectionFlag = 0 ; //A value of 0 represents single file selection while a value of 1 represents multiple file selection DesktopPlatform -> OpenFileDialog ( ParentWindowHandle , DialogTitle , DefaultPath , FString ( "" ) , FileTypes , SelectionFlag , OutFileNames ) ; } } } } void AFilePickerCharacter :: PrintData ( const FString & File ) { //Parse the data into a string array TArray < FString > LoadedText ; FFileHelper :: LoadFileToStringArray ( LoadedText , * File ) ; //Print the contents for ( int32 i = 0 ; i < LoadedText . Num ( ) ; i ++ ) { GLog -> Log ( LoadedText [ i ] ) ; } }

After compiling my code, I created the following BP code to read the contents of the single file I selected:

Here is how the file dialog looks from within the engine:

It’s worth noting that depending on the files that you want to read your print/parse data function may differ from this post. If you want to be able to select any data type you can leave the file types string empty.